From 6038baee96a7ceccced93351fc16a1063e16a5cf Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 26 Sep 2024 16:30:33 +0800 Subject: [PATCH 01/85] - move algo-ts-testing package out of puya-ts repo - add test-transformer, primitive tests, and example contracts and tests --- .gitignore | 64 + .nsprc | 2 + .prettierignore | 12 + .prettierrc.cjs | 3 + .tstoolkitrc.ts | 15 + eslint.config.mjs | 37 + examples/auction/contract.algo.ts | 140 + examples/calculator/contract.algo.ts | 90 + examples/calculator/contract.spec.ts | 48 + examples/hello-world-abi/contract.algo.ts | 18 + examples/hello-world-abi/contract.spec.ts | 27 + examples/hello-world/contract.algo.ts | 9 + examples/hello-world/contract.spec.ts | 28 + examples/simple-voting/contract.algo.ts | 47 + examples/simple-voting/contract.spec.ts | 107 + examples/tealscript/example.algo.ts | 18 + examples/tealscript/teal-script-base.algo.ts | 24 + examples/voting/contract.algo.ts | 251 + package-lock.json | 6739 +++++++++++++++++ package.json | 77 + rollup.config.ts | 38 + src/abi-metadata.ts | 60 + src/constants.ts | 37 + src/context-helpers/internal-context.ts | 74 + src/decode-logs.ts | 20 + src/errors.ts | 17 + src/impl/account.ts | 98 + src/impl/acct-params.ts | 73 + src/impl/app-params.ts | 63 + src/impl/application.ts | 69 + src/impl/asset-holding.ts | 41 + src/impl/asset-params.ts | 75 + src/impl/asset.ts | 72 + src/impl/crypto.ts | 150 + src/impl/global.ts | 190 + src/impl/gtxn.ts | 219 + src/impl/index.ts | 9 + src/impl/pure.ts | 376 + src/impl/transactions.ts | 313 + src/impl/txn.ts | 495 ++ src/index.ts | 1 + src/runtime-helpers.ts | 283 + src/subcontexts/contract-context.ts | 144 + src/subcontexts/ledger-context.ts | 79 + src/subcontexts/transaction-context.ts | 142 + src/test-execution-context.ts | 89 + src/test-transformer/errors.ts | 5 + src/test-transformer/helpers.ts | 12 + src/test-transformer/index.ts | 22 + src/test-transformer/node-factory.ts | 71 + .../supported-binary-op-string.ts | 76 + src/test-transformer/visitors.ts | 164 + src/typescript-helpers.ts | 20 + src/util.ts | 121 + src/value-generators/avm.ts | 112 + src/value-generators/index.ts | 11 + src/value-generators/txn.ts | 47 + .../created-app-asset/contract.algo.ts | 28 + .../data/CryptoOpsContract.approval.teal | 871 +++ .../data/CryptoOpsContract.arc32.json | 368 + .../data/CryptoOpsContract.clear.teal | 7 + .../MiscellaneousOpsContract.approval.teal | 1699 +++++ .../data/MiscellaneousOpsContract.arc32.json | 858 +++ .../data/MiscellaneousOpsContract.clear.teal | 7 + .../data/PrimitiveOpsContract.approval.teal | 2885 +++++++ .../data/PrimitiveOpsContract.arc32.json | 1393 ++++ .../data/PrimitiveOpsContract.clear.teal | 7 + tests/artifacts/state-ops/contract.algo.ts | 337 + .../StateAcctParamsGetContract.approval.teal | 770 ++ .../StateAcctParamsGetContract.arc32.json | 253 + .../StateAcctParamsGetContract.clear.teal | 7 + .../data/StateAppParamsContract.approval.teal | 547 ++ .../data/StateAppParamsContract.arc32.json | 199 + .../data/StateAppParamsContract.clear.teal | 7 + .../StateAssetHoldingContract.approval.teal | 115 + .../data/StateAssetHoldingContract.arc32.json | 81 + .../data/StateAssetHoldingContract.clear.teal | 7 + .../StateAssetParamsContract.approval.teal | 725 ++ .../data/StateAssetParamsContract.arc32.json | 253 + .../data/StateAssetParamsContract.clear.teal | 7 + tests/avm-invoker.ts | 136 + tests/crypto-op-codes.spec.ts | 316 + tests/primitives/biguint.spec.ts | 652 ++ tests/primitives/bytes.spec.ts | 190 + tests/primitives/uint64.spec.ts | 515 ++ tests/pure-op-codes.spec.ts | 1014 +++ tests/references/asset.spec.ts | 87 + tests/state-op-codes.spec.ts | 299 + tests/util.ts | 27 + tsconfig.build.json | 10 + tsconfig.json | 13 + vitest.config.mts | 26 + 92 files changed, 26360 insertions(+) create mode 100644 .gitignore create mode 100644 .nsprc create mode 100644 .prettierignore create mode 100644 .prettierrc.cjs create mode 100644 .tstoolkitrc.ts create mode 100644 eslint.config.mjs create mode 100644 examples/auction/contract.algo.ts create mode 100644 examples/calculator/contract.algo.ts create mode 100644 examples/calculator/contract.spec.ts create mode 100644 examples/hello-world-abi/contract.algo.ts create mode 100644 examples/hello-world-abi/contract.spec.ts create mode 100644 examples/hello-world/contract.algo.ts create mode 100644 examples/hello-world/contract.spec.ts create mode 100644 examples/simple-voting/contract.algo.ts create mode 100644 examples/simple-voting/contract.spec.ts create mode 100644 examples/tealscript/example.algo.ts create mode 100644 examples/tealscript/teal-script-base.algo.ts create mode 100644 examples/voting/contract.algo.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 rollup.config.ts create mode 100644 src/abi-metadata.ts create mode 100644 src/constants.ts create mode 100644 src/context-helpers/internal-context.ts create mode 100644 src/decode-logs.ts create mode 100644 src/errors.ts create mode 100644 src/impl/account.ts create mode 100644 src/impl/acct-params.ts create mode 100644 src/impl/app-params.ts create mode 100644 src/impl/application.ts create mode 100644 src/impl/asset-holding.ts create mode 100644 src/impl/asset-params.ts create mode 100644 src/impl/asset.ts create mode 100644 src/impl/crypto.ts create mode 100644 src/impl/global.ts create mode 100644 src/impl/gtxn.ts create mode 100644 src/impl/index.ts create mode 100644 src/impl/pure.ts create mode 100644 src/impl/transactions.ts create mode 100644 src/impl/txn.ts create mode 100644 src/index.ts create mode 100644 src/runtime-helpers.ts create mode 100644 src/subcontexts/contract-context.ts create mode 100644 src/subcontexts/ledger-context.ts create mode 100644 src/subcontexts/transaction-context.ts create mode 100644 src/test-execution-context.ts create mode 100644 src/test-transformer/errors.ts create mode 100644 src/test-transformer/helpers.ts create mode 100644 src/test-transformer/index.ts create mode 100644 src/test-transformer/node-factory.ts create mode 100644 src/test-transformer/supported-binary-op-string.ts create mode 100644 src/test-transformer/visitors.ts create mode 100644 src/typescript-helpers.ts create mode 100644 src/util.ts create mode 100644 src/value-generators/avm.ts create mode 100644 src/value-generators/index.ts create mode 100644 src/value-generators/txn.ts create mode 100644 tests/artifacts/created-app-asset/contract.algo.ts create mode 100644 tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal create mode 100644 tests/artifacts/crypto-ops/data/CryptoOpsContract.arc32.json create mode 100644 tests/artifacts/crypto-ops/data/CryptoOpsContract.clear.teal create mode 100644 tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal create mode 100644 tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json create mode 100644 tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.clear.teal create mode 100644 tests/artifacts/primitives/data/PrimitiveOpsContract.approval.teal create mode 100644 tests/artifacts/primitives/data/PrimitiveOpsContract.arc32.json create mode 100644 tests/artifacts/primitives/data/PrimitiveOpsContract.clear.teal create mode 100644 tests/artifacts/state-ops/contract.algo.ts create mode 100644 tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal create mode 100644 tests/artifacts/state-ops/data/StateAppParamsContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/StateAppParamsContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/StateAppParamsContract.clear.teal create mode 100644 tests/artifacts/state-ops/data/StateAssetHoldingContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/StateAssetHoldingContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/StateAssetHoldingContract.clear.teal create mode 100644 tests/artifacts/state-ops/data/StateAssetParamsContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/StateAssetParamsContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/StateAssetParamsContract.clear.teal create mode 100644 tests/avm-invoker.ts create mode 100644 tests/crypto-op-codes.spec.ts create mode 100644 tests/primitives/biguint.spec.ts create mode 100644 tests/primitives/bytes.spec.ts create mode 100644 tests/primitives/uint64.spec.ts create mode 100644 tests/pure-op-codes.spec.ts create mode 100644 tests/references/asset.spec.ts create mode 100644 tests/state-op-codes.spec.ts create mode 100644 tests/util.ts create mode 100644 tsconfig.build.json create mode 100644 tsconfig.json create mode 100644 vitest.config.mts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3813a4e --- /dev/null +++ b/.gitignore @@ -0,0 +1,64 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# Dependency directories +node_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# Editor/OS directories and files +.DS_Store +*.suo + +# Jetbrains +.idea/shelf/ +.idea/workspace.xml +# Editor-based HTTP Client requests +.idea/httpRequests/ +# Datasource local storage ignored files +.idea/dataSources/ +.idea/dataSources.local.xml + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# Compiled code +dist/ +build/ + +# Coverage report +coverage + +# Test results +test-results.xml + +# Website & Code docs generation +code-docs/ +out/ + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local diff --git a/.nsprc b/.nsprc new file mode 100644 index 0000000..2c63c08 --- /dev/null +++ b/.nsprc @@ -0,0 +1,2 @@ +{ +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..dbda6ae --- /dev/null +++ b/.prettierignore @@ -0,0 +1,12 @@ +# don't ever format node_modules +node_modules +# don't lint format output (make sure it's set to your correct build folder name) +dist +build +# don't format nyc coverage output +coverage +# don't format generated types +**/generated/types.d.ts +**/generated/types.ts +# don't format ide files +.idea diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 0000000..bb5f9cb --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1,3 @@ +module.exports = { + ...require('@makerx/prettier-config'), +} diff --git a/.tstoolkitrc.ts b/.tstoolkitrc.ts new file mode 100644 index 0000000..1b3e509 --- /dev/null +++ b/.tstoolkitrc.ts @@ -0,0 +1,15 @@ +import type { TsToolkitConfig } from "@makerx/ts-toolkit"; + +const config: TsToolkitConfig = { + packageConfig: { + srcDir: 'src', + outDir: 'dist', + moduleType: 'module', + main: 'index.ts', + exports: { + '.': "index.ts", + './runtime-helpers': 'runtime-helpers.ts' + } + } +} +export default config diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..4351651 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,37 @@ +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) +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}) + +export default [ + { + ignores: [ + '**/.eslintrc.js', + '**/node_modules', + '**/dist', + '**/build', + '**/coverage', + '**/generated/types.d.ts', + '**/generated/types.ts', + '**/.idea', + '**/.vscode', + ], + }, + ...compat.extends('@makerx/eslint-config'), + { + languageOptions: { + globals: { + ...globals.node, + }, + }, + }, +] diff --git a/examples/auction/contract.algo.ts b/examples/auction/contract.algo.ts new file mode 100644 index 0000000..810cba0 --- /dev/null +++ b/examples/auction/contract.algo.ts @@ -0,0 +1,140 @@ +import type { gtxn, uint64 } from '@algorandfoundation/algo-ts' +import { + abimethod, + Account, + assert, + assertMatch, + Asset, + Contract, + Global, + GlobalState, + itxn, + LocalState, + Txn, +} from '@algorandfoundation/algo-ts' + +export class Auction extends Contract { + previousBidder = GlobalState() + + auctionEnd = GlobalState() + + previousBid = GlobalState() + + asaAmt = GlobalState() + + asa = GlobalState() + + claimableAmount = LocalState() + + @abimethod({ allowActions: 'NoOp', onCreate: 'require' }) + public createApplication(): void { + this.auctionEnd.value = 0 + this.previousBid.value = 0 + this.asaAmt.value = 0 + this.asa.value = Asset() + + // Use zero address rather than an empty string for Account type safety + this.previousBidder.value = Account() + } + + public optIntoAsset(asset: Asset): void { + /// Only allow app creator to opt the app account into a ASA + assertMatch(Txn, { sender: Global.creatorAddress }) + + /// Verify a ASA hasn't already been opted into + assert(this.asa.value === Asset()) + + /// Save ASA ID in global state + this.asa.value = asset + + /// Submit opt-in transaction: 0 asset transfer to self + itxn + .assetTransfer({ + assetReceiver: Global.currentApplicationAddress, + xferAsset: asset, + assetAmount: 0, + }) + .submit() + } + + public startAuction(startingPrice: uint64, length: uint64, axfer: gtxn.AssetTransferTxn): void { + assertMatch(Txn, { sender: Global.creatorAddress }) + + /// Ensure the auction hasn't already been started + assert(this.auctionEnd.value === 0) + + /// Verify axfer + assertMatch(axfer, { assetReceiver: Global.currentApplicationAddress }) + + /// Set global state + this.asaAmt.value = axfer.assetAmount + this.auctionEnd.value = Global.latestTimestamp + length + this.previousBid.value = startingPrice + } + + private pay(receiver: Account, amount: uint64): void { + itxn + .payment({ + receiver: receiver, + amount: amount, + }) + .submit() + } + + @abimethod({ allowActions: 'OptIn' }) + public optInToApplication(): void {} + + public bid(payment: gtxn.PaymentTxn): void { + /// Ensure auction hasn't ended + assert(Global.latestTimestamp < this.auctionEnd.value) + + /// Verify payment transaction + assertMatch(payment, { + sender: Txn.sender, + amount: { greaterThan: this.previousBid.value }, + }) + + /// Set global state + this.previousBid.value = payment.amount + this.previousBidder.value = payment.sender + + /// Update claimable amount + this.claimableAmount(Txn.sender).value = payment.amount + } + + public claimBids(): void { + const originalAmount = this.claimableAmount(Txn.sender).value + let amount = originalAmount + + /// subtract previous bid if sender is previous bidder + if (Txn.sender === this.previousBidder.value) amount = amount - this.previousBid.value + + this.pay(Txn.sender, amount) + this.claimableAmount(Txn.sender).value = originalAmount - amount + } + + public claimAsset(asset: Asset): void { + assert(Global.latestTimestamp > this.auctionEnd.value) + + /// Send ASA to previous bidder + itxn + .assetTransfer({ + assetReceiver: this.previousBidder.value, + xferAsset: asset, + assetAmount: this.asaAmt.value, + assetCloseTo: this.previousBidder.value, + }) + .submit() + } + + @abimethod({ allowActions: 'DeleteApplication' }) + public deleteApplication(): void { + itxn + .payment({ + receiver: Global.creatorAddress, + closeRemainderTo: Global.creatorAddress, + amount: 0, + }) + .submit() + } +} diff --git a/examples/calculator/contract.algo.ts b/examples/calculator/contract.algo.ts new file mode 100644 index 0000000..f21a5f8 --- /dev/null +++ b/examples/calculator/contract.algo.ts @@ -0,0 +1,90 @@ +import type { uint64 } from '@algorandfoundation/algo-ts' +import { assert, Bytes, Contract, err, log, op, Txn, Uint64 } from '@algorandfoundation/algo-ts' + +const ADD = Uint64(1) +const SUB = Uint64(2) +const MUL = Uint64(3) +const DIV = Uint64(4) +function itoa(i: uint64): string { + const digits = Bytes`0123456789` + const radix = digits.length + if (i < radix) { + return digits.at(i).toString() + } + return itoa(i / radix).concat(digits.at(i % radix).toString()) +} +export default class MyContract extends Contract { + public approvalProgram(): boolean { + const numArgs = Txn.numAppArgs + let a: uint64, b: uint64, action: uint64 + if (numArgs === 0) { + a = 0 + b = 0 + action = Uint64(0) + log(a) + log(b) + } else { + assert(numArgs === 3, 'Expected 3 args') + action = op.btoi(Txn.applicationArgs(0)) + const a_bytes = Txn.applicationArgs(1) + const b_bytes = Txn.applicationArgs(2) + log(a_bytes) + log(b_bytes) + a = op.btoi(a_bytes) + b = op.btoi(b_bytes) + } + const result = this.doCalc(action, a, b) + const result_b = `${itoa(a)}${this.op(action)}${itoa(b)} = ${itoa(result)}` + log(result_b) + return true + } + public op(action: uint64): string { + switch (action) { + case ADD: + return ` + ` + case SUB: + return ` - ` + case MUL: + return ` * ` + case DIV: + return ` / ` + default: + err('Unknown operation') + } + } + + public doCalc(action: uint64, a: uint64, b: uint64): uint64 { + switch (action) { + case ADD: + return this.add(a, b) + case SUB: + return this.sub(a, b) + case MUL: + return this.mul(a, b) + case DIV: + return this.div(a, b) + default: + err('Unknown operation') + } + } + + private add(a: uint64, b: uint64): uint64 { + return a + b + } + + private sub(a: uint64, b: uint64): uint64 { + return a - b + } + + private mul(a: uint64, b: uint64): uint64 { + return a * b + } + + private div(a: uint64, b: uint64): uint64 { + return a / b + } + + public clearState(): boolean { + return true + } +} diff --git a/examples/calculator/contract.spec.ts b/examples/calculator/contract.spec.ts new file mode 100644 index 0000000..5bf6a56 --- /dev/null +++ b/examples/calculator/contract.spec.ts @@ -0,0 +1,48 @@ +import { internal, op, Uint64 } from '@algorandfoundation/algo-ts' +import { afterEach, describe, expect, it } from 'vitest' + +import { TestExecutionContext } from '@algorandfoundation/algo-ts-testing' +import MyContract from './contract.algo' + +describe('Calculator', () => { + const ctx = new TestExecutionContext() + afterEach(() => { + ctx.reset() + }) + describe('when calling with with no args', () => { + it('errors', async () => { + const contract = ctx.contract.create(MyContract) + ctx.txn + .createScope([ + ctx.any.txn.applicationCall({ + appId: ctx.ledger.getApplicationForContract(contract), + appArgs: [], + }), + ]) + .execute(() => { + expect(() => contract.approvalProgram()).toThrowError(new internal.errors.AvmError('Unknown operation')) + }) + }) + }) + describe('when calling with with three args', () => { + it('Returns 1', async () => { + const contract = ctx.contract.create(MyContract) + const application = ctx.ledger.getApplicationForContract(contract) + const result = ctx.txn + .createScope([ + ctx.any.txn.applicationCall({ + appId: application, + appArgs: [op.itob(Uint64(1)), op.itob(Uint64(2)), op.itob(Uint64(3))], + }), + ]) + .execute(contract.approvalProgram) + + const [left, right, outcome] = ctx.exportLogs(application.id, 'i', 'i', 's') + + expect(left).toBe(2n) + expect(right).toBe(3n) + expect(outcome).toBe('2 + 3 = 5') + expect(result).toBe(true) + }) + }) +}) diff --git a/examples/hello-world-abi/contract.algo.ts b/examples/hello-world-abi/contract.algo.ts new file mode 100644 index 0000000..1636f50 --- /dev/null +++ b/examples/hello-world-abi/contract.algo.ts @@ -0,0 +1,18 @@ +import { arc4, log } from '@algorandfoundation/algo-ts' + +abstract class Intermediate extends arc4.Contract { + @arc4.abimethod({ allowActions: ['NoOp'], readonly: true }) + public sayBananas(): string { + const result = `Bananas` + log(result) + return result + } +} + +export default class HelloWorldContract extends Intermediate { + public sayHello(firstName: string, lastName: string): string { + const result = `Hello ${firstName} ${lastName}` + log(result) + return result + } +} diff --git a/examples/hello-world-abi/contract.spec.ts b/examples/hello-world-abi/contract.spec.ts new file mode 100644 index 0000000..1cd18fb --- /dev/null +++ b/examples/hello-world-abi/contract.spec.ts @@ -0,0 +1,27 @@ +import { assert, TransactionType } from '@algorandfoundation/algo-ts' +import { TestExecutionContext } from '@algorandfoundation/algo-ts-testing' +import { afterEach, describe, expect, it } from 'vitest' +import HelloWorldContract from './contract.algo' + +describe('HelloWorldContract', () => { + const ctx = new TestExecutionContext() + afterEach(() => { + ctx.reset() + }) + it('logs the returned value when sayBananas is called', async () => { + const contract = ctx.contract.create(HelloWorldContract) + const result = contract.sayBananas() + assert(ctx.txn.lastActive.type === TransactionType.ApplicationCall, 'Last txn must be app') + + expect(result).toBe('Bananas') + expect(ctx.exportLogs(ctx.txn.lastActive.appId.id, 's')).toStrictEqual([result]) + }) + it('logs the returned value when sayHello is called', async () => { + const contract = ctx.contract.create(HelloWorldContract) + const result = contract.sayHello('John', 'Doe') + assert(ctx.txn.lastActive.type === TransactionType.ApplicationCall, 'Last txn must be app') + + expect(result).toBe('Hello John Doe') + expect(ctx.exportLogs(ctx.txn.lastActive.appId.id, 's')).toStrictEqual([result]) + }) +}) diff --git a/examples/hello-world/contract.algo.ts b/examples/hello-world/contract.algo.ts new file mode 100644 index 0000000..6ac05f7 --- /dev/null +++ b/examples/hello-world/contract.algo.ts @@ -0,0 +1,9 @@ +import { BaseContract, log, op } from '@algorandfoundation/algo-ts' + +export default class HelloWorldContract extends BaseContract { + public approvalProgram(): boolean { + const name = String(op.Txn.applicationArgs(0)) + log(`Hello, ${name}`) + return true + } +} diff --git a/examples/hello-world/contract.spec.ts b/examples/hello-world/contract.spec.ts new file mode 100644 index 0000000..1e6b20d --- /dev/null +++ b/examples/hello-world/contract.spec.ts @@ -0,0 +1,28 @@ +import { Bytes } from '@algorandfoundation/algo-ts' +import { TestExecutionContext } from '@algorandfoundation/algo-ts-testing' +import { afterEach, describe, expect, it } from 'vitest' +import HelloWorldContract from './contract.algo' + +describe('When calling the HelloWorldContract', () => { + const ctx = new TestExecutionContext() + afterEach(() => { + ctx.reset() + }) + describe("with ['world']", () => { + it('logs Hello, World', async () => { + const contract = ctx.contract.create(HelloWorldContract) + const application = ctx.ledger.getApplicationForContract(contract) + const result = ctx.txn + .createScope([ + ctx.any.txn.applicationCall({ + appId: application, + appArgs: [Bytes('World')], + }), + ]) + .execute(contract.approvalProgram) + + expect(ctx.exportLogs(application.id, 's')).toStrictEqual(['Hello, World']) + expect(result).toBe(true) + }) + }) +}) diff --git a/examples/simple-voting/contract.algo.ts b/examples/simple-voting/contract.algo.ts new file mode 100644 index 0000000..6d8b2f5 --- /dev/null +++ b/examples/simple-voting/contract.algo.ts @@ -0,0 +1,47 @@ +import type { Account, bytes, uint64 } from '@algorandfoundation/algo-ts' +import { assert, BaseContract, Bytes, GlobalState, LocalState, op, TransactionType, Uint64 } from '@algorandfoundation/algo-ts' + +const VOTE_PRICE = Uint64(10_000) +export default class SimpleVotingContract extends BaseContract { + topic = GlobalState({ initialValue: Bytes('default_topic'), key: Bytes('topic') }) + votes = GlobalState({ initialValue: Uint64(0), key: Bytes('votes') }) + voted = LocalState() + + public approvalProgram(): uint64 { + switch (op.Txn.applicationArgs(0)) { + case Bytes('set_topic'): { + this.setTopic(op.Txn.applicationArgs(1)) + return Uint64(1) + } + case Bytes('vote'): { + return this.vote(op.Txn.sender) ? Uint64(1) : Uint64(0) + } + case Bytes('get_votes'): { + return this.votes.value + } + default: + return Uint64(0) + } + } + + public clearStateProgram(): boolean { + return true + } + + private setTopic(topic: bytes): void { + this.topic.value = topic + } + + private vote(voter: Account): boolean { + assert(op.Global.groupSize === Uint64(2)) + assert(op.GTxn.amount(1) === VOTE_PRICE) + assert(op.GTxn.typeEnum(1) === TransactionType.Payment) + + if (this.voted(voter).hasValue) { + return false + } + this.votes.value = this.votes.value + 1 + this.voted(voter).value = Uint64(1) + return true + } +} diff --git a/examples/simple-voting/contract.spec.ts b/examples/simple-voting/contract.spec.ts new file mode 100644 index 0000000..9d5ed07 --- /dev/null +++ b/examples/simple-voting/contract.spec.ts @@ -0,0 +1,107 @@ +import type { Account, uint64 } from '@algorandfoundation/algo-ts' +import { Bytes, Uint64 } from '@algorandfoundation/algo-ts' +import { TestExecutionContext } from '@algorandfoundation/algo-ts-testing' +import { afterEach, describe, expect, it } from 'vitest' +import SimpleVotingContract from './contract.algo' + +describe('Simple voting contract', () => { + const ctx = new TestExecutionContext() + afterEach(() => { + ctx.reset() + }) + describe('When setting the topic', () => { + describe('with correct arguments', () => { + it('should set the topic', async () => { + const contract = ctx.contract.create(SimpleVotingContract) + const topic = Bytes('new_topic') + + const result = ctx.txn + .createScope( + [ + ctx.any.txn.applicationCall({ + appId: ctx.ledger.getApplicationForContract(contract), + appArgs: [Bytes('set_topic'), topic], + }), + ctx.any.txn.payment({ + amount: Uint64(10_000), + }), + ], + 0, + ) + .execute(contract.approvalProgram) + + expect(result).toEqual(Uint64(1)) + expect(contract.topic.value.toString()).toBe(topic.toString()) + }) + }) + }) + describe('When voting', () => { + it('records the vote correctly', async () => { + const contract = ctx.contract.create(SimpleVotingContract) + contract.votes.value = Uint64(0) + const voter = ctx.defaultSender + + 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)) + }) + it('ignores subsequent votes from the same voter', async () => { + const contract = ctx.contract.create(SimpleVotingContract) + const voter = ctx.any.account() + contract.voted(voter).value = Uint64(1) + contract.votes.value = Uint64(1) + + 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)) + }) + }) + describe('When getting the votes', () => { + it('returns the correct number of votes', async () => { + const contract = ctx.contract.create(SimpleVotingContract) + const voter1 = ctx.any.account() + const voter2 = ctx.any.account() + castVote(ctx, contract, voter1) + castVote(ctx, contract, voter2) + + const result = ctx.txn + .createScope( + [ + ctx.any.txn.applicationCall({ + appId: ctx.ledger.getApplicationForContract(contract), + appArgs: [Bytes('get_votes')], + }), + ctx.any.txn.payment({ + amount: Uint64(10_000), + }), + ], + 0, + ) + .execute(contract.approvalProgram) + + expect(result).toEqual(Uint64(2)) + }) + }) +}) + +const castVote = (ctx: TestExecutionContext, contract: SimpleVotingContract, voter: Account): uint64 => + ctx.txn + .createScope( + [ + ctx.any.txn.applicationCall({ + appId: ctx.ledger.getApplicationForContract(contract), + sender: voter, + appArgs: [Bytes('vote'), voter.bytes], + }), + ctx.any.txn.payment({ + sender: voter, + amount: Uint64(10_000), + }), + ], + 0, + ) + .execute(contract.approvalProgram) diff --git a/examples/tealscript/example.algo.ts b/examples/tealscript/example.algo.ts new file mode 100644 index 0000000..b013331 --- /dev/null +++ b/examples/tealscript/example.algo.ts @@ -0,0 +1,18 @@ +import type { bytes } from '@algorandfoundation/algo-ts' +import { abimethod, Bytes, log, Uint64 } from '@algorandfoundation/algo-ts' +import { TealScriptBase } from './teal-script-base.algo' + +export default class ExampleTealScript extends TealScriptBase { + public createApplication() { + log('Application created') + + super.createApplication() + + return Uint64(4) + } + + @abimethod({ allowActions: ['NoOp', 'OptIn'], name: 'Overridden name', onCreate: 'allow', readonly: false }) + public customMethod(): bytes { + return Bytes('') + } +} diff --git a/examples/tealscript/teal-script-base.algo.ts b/examples/tealscript/teal-script-base.algo.ts new file mode 100644 index 0000000..1cbb963 --- /dev/null +++ b/examples/tealscript/teal-script-base.algo.ts @@ -0,0 +1,24 @@ +import { arc4, Contract, err } from '@algorandfoundation/algo-ts' + +export abstract class TealScriptBase extends Contract { + @arc4.abimethod({ allowActions: 'DeleteApplication' }) + public deleteApplication(): void { + err('not supported') + } + @arc4.abimethod({ allowActions: 'NoOp', onCreate: 'require' }) + public createApplication(): void { + err('not supported') + } + @arc4.abimethod({ allowActions: 'UpdateApplication' }) + public updateApplication(): void { + err('not supported') + } + @arc4.abimethod({ allowActions: 'OptIn' }) + public optInToApplication(): void { + err('not supported') + } + @arc4.abimethod({ allowActions: 'CloseOut' }) + public closeOutOfApplication(): void { + err('not supported') + } +} diff --git a/examples/voting/contract.algo.ts b/examples/voting/contract.algo.ts new file mode 100644 index 0000000..42e2949 --- /dev/null +++ b/examples/voting/contract.algo.ts @@ -0,0 +1,251 @@ +import type { Account, Asset, bytes, gtxn, uint64 } from '@algorandfoundation/algo-ts' +import { + abimethod, + arc4, + assert, + assertMatch, + BoxMap, + BoxRef, + Bytes, + ensureBudget, + Global, + GlobalState, + itxn, + log, + op, + OpUpFeeSource, + Txn, + Uint64, + urange, +} from '@algorandfoundation/algo-ts' + +type VoteIndexArray = arc4.DynamicArray> + +const VOTE_INDEX_BYTES: uint64 = 1 +const VOTE_COUNT_BYTES: uint64 = 8 + +// The min balance increase per box created +const BOX_FLAT_MIN_BALANCE: uint64 = 2500 + +// The min balance increase per byte of boxes (key included) +const BOX_BYTE_MIN_BALANCE: uint64 = 400 + +// The min balance increase for each asset opted into +const ASSET_MIN_BALANCE: uint64 = 100000 + +// TODO: ObjectPType should hopefully respect this ordering of properties +type VotingPreconditions = { + is_voting_open: uint64 + is_allowed_to_vote: uint64 + has_already_voted: uint64 + current_time: uint64 +} +export class VotingRoundApp extends arc4.Contract { + isBootstrapped = GlobalState({ initialValue: false }) + voterCount = GlobalState({ initialValue: Uint64(0) }) + closeTime = GlobalState() + tallyBox = BoxRef({ key: Bytes`V` }) + votesByAccount = BoxMap({ keyPrefix: Bytes() }) + voteId = GlobalState() + snapshotPublicKey = GlobalState() + metadataIpfsCid = GlobalState() + startTime = GlobalState() + nftImageUrl = GlobalState() + endTime = GlobalState() + quorum = GlobalState() + optionCounts = GlobalState() + totalOptions = GlobalState() + nftAsset = GlobalState() + + @abimethod({ onCreate: 'require' }) + public create( + voteId: string, + snapshotPublicKey: bytes, + metadataIpfsCid: string, + startTime: uint64, + endTime: uint64, + optionCounts: VoteIndexArray, + quorum: uint64, + nftImageUrl: string, + ): void { + assert(startTime < endTime, 'End time should be after start time') + assert(endTime >= Global.latestTimestamp, 'End time should be in the future') + + this.voteId.value = voteId + this.snapshotPublicKey.value = snapshotPublicKey + this.metadataIpfsCid.value = metadataIpfsCid + this.startTime.value = startTime + this.endTime.value = endTime + this.quorum.value = quorum + this.nftImageUrl.value = nftImageUrl + this.storeOptionCounts(optionCounts) + } + + public bootstrap(fundMinBalReq: gtxn.PaymentTxn): void { + assert(!this.isBootstrapped.value, 'Must not be already bootstrapped') + this.isBootstrapped.value = true + assertMatch( + fundMinBalReq, + { + receiver: Global.currentApplicationAddress, + }, + 'Payment must be to app address', + ) + const tallyBoxSize: uint64 = this.totalOptions.value * VOTE_COUNT_BYTES + + const minBalanceReq: uint64 = + ASSET_MIN_BALANCE * 2 + 1000 + BOX_FLAT_MIN_BALANCE + BOX_BYTE_MIN_BALANCE + tallyBoxSize * BOX_BYTE_MIN_BALANCE + + log(minBalanceReq) + + assertMatch( + fundMinBalReq, + { + amount: minBalanceReq, + }, + 'Payment must be for the exact min balance requirement', + ) + assert(this.tallyBox.create({ size: tallyBoxSize })) + } + + public close() { + ensureBudget(20000) + assert(!this.closeTime.hasValue, 'Already closed') + this.closeTime.value = Global.latestTimestamp + + // Do we need a way to declare string literals where we ignore leading whitespace? + let note = `{ + "standard":"arc69", + "description":"This is a voting result NFT for voting round with ID ${this.voteId.value}", + "properties":{ + "metadata":"ipfs://${this.metadataIpfsCid.value}", + "id":"${this.voteId.value}", + "quorum":"${itoa(this.quorum.value)}}", + "voterCount":"${itoa(this.voterCount.value)}", + "tallies": [` + + let currentIndex = Uint64(0) + for (const [questionIndex, questionOptions] of this.optionCounts.value.entries()) { + if (questionIndex > 0) { + note += ',' + } + if (questionOptions.native > 0) { + note += '[' + for (let optionIndex = Uint64(0); optionIndex <= questionOptions.native; optionIndex++) { + if (optionIndex > 0) { + note += ',' + } + note += itoa(this.getVoteFromBox(currentIndex)) + currentIndex += 1 + } + note += ']' + } + } + note += ']}}' + + this.nftAsset.value = itxn + .assetConfig({ + total: 1, + decimals: 0, + defaultFrozen: false, + assetName: `[VOTE RESULT] ${this.voteId.value}`, + unitName: `VOTERSLT`, + url: this.nftImageUrl.value, + note: note, + fee: Global.minTxnFee, + }) + .submit().configAsset + } + + @abimethod({ readonly: true }) + public getPreconditions(signature: bytes): VotingPreconditions { + return { + is_allowed_to_vote: Uint64(this.allowedToVote(signature)), + is_voting_open: Uint64(this.votingOpen()), + has_already_voted: Uint64(this.alreadyVoted()), + current_time: Global.latestTimestamp, + } + } + + private allowedToVote(signature: bytes): boolean { + ensureBudget(2000) + return op.ed25519verifyBare(Txn.sender.bytes, signature, this.snapshotPublicKey.value) + } + + private alreadyVoted(): boolean { + return this.votesByAccount.has(Txn.sender) + } + + public vote(fundMinBalReq: gtxn.PaymentTxn, signature: bytes, answerIds: VoteIndexArray): void { + ensureBudget(7700, OpUpFeeSource.GroupCredit) + assert(this.allowedToVote(signature), 'Not allowed to vote') + assert(this.votingOpen(), 'Voting not open') + assert(!this.alreadyVoted(), 'Already voted') + + const questionsCount = this.optionCounts.value.length + assertMatch( + answerIds, + { + length: questionsCount, + }, + 'Number of answers incorrect', + ) + const minBalReq: uint64 = BOX_FLAT_MIN_BALANCE + (32 + 2 + VOTE_INDEX_BYTES * answerIds.length) * BOX_BYTE_MIN_BALANCE + log(minBalReq) + assertMatch( + fundMinBalReq, + { + receiver: Global.currentApplicationAddress, + amount: minBalReq, + }, + 'Payment must be to app and for exactly min balance', + ) + let cumulativeOffset = Uint64(0) + for (const questionIndex of urange(questionsCount)) { + const answerOptionIndex = answerIds.at(questionIndex).native + const optionsCount = this.optionCounts.value.at(questionIndex).native + assert(answerOptionIndex < optionsCount, 'Answer option index invalid') + this.incrementVoteInBox(cumulativeOffset + answerOptionIndex) + cumulativeOffset += optionsCount + this.votesByAccount.set(Txn.sender, answerIds.copy()) + this.voterCount.value += 1 + } + } + + private votingOpen(): boolean { + return ( + this.isBootstrapped.value && + !this.closeTime.hasValue && + this.startTime.value <= Global.latestTimestamp && + Global.latestTimestamp <= this.endTime.value + ) + } + + private storeOptionCounts(optionCounts: VoteIndexArray) { + assertMatch(optionCounts, { length: { between: [Uint64(1), Uint64(112)] } }) + + let totalOptions = Uint64(0) + for (const item of optionCounts) { + totalOptions += item.native + } + this.optionCounts.value = optionCounts.copy() + this.totalOptions.value = totalOptions + } + + private getVoteFromBox(index: uint64): uint64 { + return op.btoi(this.tallyBox.extract(index, VOTE_COUNT_BYTES)) + } + + private incrementVoteInBox(index: uint64): void { + const currentVote = this.getVoteFromBox(index) + this.tallyBox.replace(index, op.itob(currentVote + 1)) + } +} +function itoa(i: uint64): string { + const digits = Bytes`0123456789` + const radix = digits.length + if (i < radix) { + return digits.at(i).toString() + } + return `${itoa(i / radix)}${digits.at(i % radix)}` +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..09a4e69 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6739 @@ +{ + "name": "@algorandfoundation/algo-ts-testing", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@algorandfoundation/algo-ts-testing", + "version": "1.0.0", + "dependencies": { + "@algorandfoundation/algokit-utils": "^6.2.1", + "algosdk": "^2.9.0", + "elliptic": "^6.5.7", + "js-sha256": "^0.11.0", + "js-sha3": "^0.9.3", + "js-sha512": "^0.9.0", + "tweetnacl": "^1.0.3" + }, + "devDependencies": { + "@algorandfoundation/algo-ts": "file:../puya-ts/packages/algo-ts/dist", + "@algorandfoundation/algo-ts-testing": "file:./dist", + "@algorandfoundation/puya-ts": "file:../puya-ts/dist", + "@eslint/eslintrc": "3.1.0", + "@eslint/js": "9.11.1", + "@makerx/eslint-config": "4.0.0", + "@makerx/prettier-config": "2.0.1", + "@makerx/ts-toolkit": "4.0.0-beta.20", + "@rollup/plugin-commonjs": "28.0.0", + "@rollup/plugin-json": "6.1.0", + "@rollup/plugin-node-resolve": "15.3.0", + "@rollup/plugin-typescript": "^12.1.0", + "@tsconfig/node20": "20.1.4", + "@types/elliptic": "^6.4.18", + "@types/node": "22.6.1", + "@typescript-eslint/eslint-plugin": "8.7.0", + "@typescript-eslint/parser": "8.7.0", + "@vitest/coverage-v8": "2.1.1", + "better-npm-audit": "3.11.0", + "copyfiles": "2.4.1", + "eslint": "9.11.1", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "npm-run-all": "4.1.5", + "prettier": "3.3.3", + "rimraf": "6.0.1", + "rollup": "^4.22.4", + "tsx": "4.19.1", + "typescript": "^5.6.2", + "vitest": "2.1.1" + }, + "peerDependencies": { + "@algorandfoundation/algo-ts": "*", + "@algorandfoundation/puya-ts": "*", + "tslib": "^2.6.2" + } + }, + "../algo-ts/dist": { + "name": "@algorandfoundation/algo-ts", + "version": "1.0.0", + "extraneous": true, + "peerDependencies": { + "tslib": "^2.6.2" + } + }, + "../puya-ts/dist": { + "name": "@algorandfoundation/puya-ts", + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "change-case": "^5.4.4", + "commander": "^12.1.0", + "cross-spawn": "^7.0.3", + "glob": "^11.0.0", + "polytype": "^0.17.0", + "zod": "^3.23.8" + } + }, + "../puya-ts/packages/algo-ts/dist": { + "name": "@algorandfoundation/algo-ts", + "version": "1.0.0", + "dev": true, + "peerDependencies": { + "tslib": "^2.6.2" + } + }, + "dist": { + "name": "@algorandfoundation/algo-ts-testing", + "version": "1.0.0", + "dev": true, + "dependencies": { + "@algorandfoundation/algokit-utils": "^6.2.1", + "algosdk": "^2.9.0", + "elliptic": "^6.5.7", + "js-sha256": "^0.11.0", + "js-sha3": "^0.9.3", + "js-sha512": "^0.9.0", + "tweetnacl": "^1.0.3" + }, + "peerDependencies": { + "@algorandfoundation/algo-ts": "*", + "@algorandfoundation/puya-ts": "*", + "tslib": "^2.6.2" + } + }, + "node_modules/@algorandfoundation/algo-ts": { + "resolved": "../puya-ts/packages/algo-ts/dist", + "link": true + }, + "node_modules/@algorandfoundation/algo-ts-testing": { + "resolved": "dist", + "link": true + }, + "node_modules/@algorandfoundation/algokit-utils": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-utils/-/algokit-utils-6.2.1.tgz", + "integrity": "sha512-oJbqT91KJp34OasYID2guWHysCLdgZ/4GVb06sdgXxORWKKMhZa/Uj12UiACo4VzZJBOUZEJCh/QrSuHmu/m2g==", + "dependencies": { + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "algosdk": "^2.7.0" + } + }, + "node_modules/@algorandfoundation/puya-ts": { + "resolved": "../puya-ts/dist", + "link": true + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "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==", + "dev": true + }, + "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==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "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==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "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/core": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", + "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "dev": true, + "license": "Apache-2.0", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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/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.11.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", + "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", + "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@makerx/eslint-config": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@makerx/eslint-config/-/eslint-config-4.0.0.tgz", + "integrity": "sha512-uuYABtaZWoR9T1fJb1lCSKLsdQwVpQaQw96QM/H893svTHVWDB9w1kX7l1tp5TMC8FOymS4ICM9xxFOBKTiR9A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@makerx/prettier-config": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@makerx/prettier-config/-/prettier-config-2.0.1.tgz", + "integrity": "sha512-fI2TT312JPVrgNFASiZG8b7N4RjazYvxEd7Yq05jwTdZyTiT9eRGjKHSRc+MA9uPBeOVLWNI7PKYTCqyXTw7uA==", + "dev": true + }, + "node_modules/@makerx/ts-toolkit": { + "version": "4.0.0-beta.20", + "resolved": "https://registry.npmjs.org/@makerx/ts-toolkit/-/ts-toolkit-4.0.0-beta.20.tgz", + "integrity": "sha512-faZyycGxk7lKvhm0nwy5hirwD6tVAdLLbEYh9kd13OzHuWiHPySt3ixdB2BXHDzoE65BU43h8X/pqlUNDbH4NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "commander": "^12.1.0", + "compare-versions": "^6.1.1", + "cosmiconfig": "^9.0.0" + }, + "bin": { + "ts-toolkit": "bin/run-cli.js", + "tstk": "bin/run-cli.js" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.1.1", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "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", + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-typescript": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.0.tgz", + "integrity": "sha512-Kzs8KGJofe7cfTRODsnG1jNGxSvU8gVoNNd7Z/QaY25AYwe2LSSUpx/kPxqF38NYkpR8de3m51r9uwJpDlz6dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0||^3.0.0||^4.0.0", + "tslib": "*", + "typescript": ">=3.7.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "tslib": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/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/rollup-android-arm-eabi": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tsconfig/node20": { + "version": "20.1.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz", + "integrity": "sha512-sqgsT69YFeLWf5NtJ4Xq/xAF8p4ZQHlmGW74Nu2tD4+g5fAsposc4ZfaaPixVu4y01BEiDCWLRDCvDM5JOsRxg==", + "dev": true + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/elliptic": { + "version": "6.4.18", + "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.18.tgz", + "integrity": "sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw==", + "dev": true, + "dependencies": { + "@types/bn.js": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.6.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.6.1.tgz", + "integrity": "sha512-V48tCfcKb/e6cVUigLAaJDAILdMP0fUW6BidkPK4GpGjXcfbnoHasCZDwz3N3yVt5we2RHm4XTQCpv0KJz9zqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz", + "integrity": "sha512-RIHOoznhA3CCfSTFiB6kBGLQtB/sox+pJ6jeFu6FxJvqL8qRxq/FfGO/UhsGgQM9oGdXkV4xUgli+dt26biB6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.7.0", + "@typescript-eslint/type-utils": "8.7.0", + "@typescript-eslint/utils": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.7.0.tgz", + "integrity": "sha512-lN0btVpj2unxHlNYLI//BQ7nzbMJYBVQX5+pbNXvGYazdlgYonMn4AhhHifQ+J4fGRYA/m1DjaQjx+fDetqBOQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "8.7.0", + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/typescript-estree": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz", + "integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.7.0.tgz", + "integrity": "sha512-tl0N0Mj3hMSkEYhLkjREp54OSb/FI6qyCzfiiclvJvOqre6hsZTGSnHtmFLDU8TIM62G7ygEa1bI08lcuRwEnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.7.0", + "@typescript-eslint/utils": "8.7.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz", + "integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz", + "integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0", + "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" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz", + "integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.7.0", + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/typescript-estree": "8.7.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz", + "integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.7.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.1.tgz", + "integrity": "sha512-md/A7A3c42oTT8JUHSqjP5uKTWJejzUW4jalpvs+rZ27gsURsMU8DEb+8Jf8C6Kj2gwfSHJqobDNBuoqlm0cFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.6", + "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", + "test-exclude": "^7.0.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "2.1.1", + "vitest": "2.1.1" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.1.tgz", + "integrity": "sha512-YeueunS0HiHiQxk+KEOnq/QMzlUuOzbU1Go+PgAsHvvv3tUkJPm9xWt+6ITNTlzsMXUjmgm5T+U7KBPK2qQV6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.1", + "@vitest/utils": "2.1.1", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.1.tgz", + "integrity": "sha512-LNN5VwOEdJqCmJ/2XJBywB11DLlkbY0ooDJW3uRX5cZyYCrc4PI/ePX0iQhE3BiEGiQmK4GE7Q/PqCkkaiPnrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "^2.1.0-beta.1", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.11" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/spy": "2.1.1", + "msw": "^2.3.5", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.1.tgz", + "integrity": "sha512-SjxPFOtuINDUW8/UkElJYQSFtnWX7tMksSGW0vfjxMneFqxVr8YJ979QpMbDW7g+BIiq88RAGDjf7en6rvLPPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.1.tgz", + "integrity": "sha512-uTPuY6PWOYitIkLPidaY5L3t0JJITdGTSwBtwMjKzo5O6RCOEncz9PUN+0pDidX8kTHYjO0EwUIvhlGpnGpxmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.1", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.1.tgz", + "integrity": "sha512-BnSku1WFy7r4mm96ha2FzN99AZJgpZOWrAhtQfoxjUU5YMRpq1zmHRq7a5K9/NjqonebO7iVDla+VvZS8BOWMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.1", + "magic-string": "^0.30.11", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.1.tgz", + "integrity": "sha512-ZM39BnZ9t/xZ/nF4UwRH5il0Sw93QnZXd9NAZGRpIgj0yvVwPpLd702s/Cx955rGaMlyBQkZJ2Ir7qyY48VZ+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.1.tgz", + "integrity": "sha512-Y6Q9TsI+qJ2CC0ZKj6VBb+T8UPz593N113nnUykqwANqhgf3QkZeHFlusgKLTqrnVHbj/XDKZcDHol+dxVT+rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.1", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/algo-msgpack-with-bigint": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", + "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/algosdk": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-2.9.0.tgz", + "integrity": "sha512-o0n0nLMbTX6SFQdMUk2/2sy50jmEmZk5OTPYSh2aAeP8DUPxrhjMPfwGsYNvaO+qk75MixC2eWpfA9vygCQ/Mg==", + "license": "MIT", + "dependencies": { + "algo-msgpack-with-bigint": "^2.1.1", + "buffer": "^6.0.3", + "hi-base32": "^0.5.1", + "js-sha256": "^0.9.0", + "js-sha3": "^0.8.0", + "js-sha512": "^0.8.0", + "json-bigint": "^1.0.0", + "tweetnacl": "^1.0.3", + "vlq": "^2.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/algosdk/node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "node_modules/algosdk/node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/algosdk/node_modules/js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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 + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/better-npm-audit": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/better-npm-audit/-/better-npm-audit-3.11.0.tgz", + "integrity": "sha512-/Pt05DK6HQaRjWDc5McsCkJBZYfhgQGneKnxzPJExtRq38NttO1Hm30m0GVQeZogE94LVNBVrhWwVsoCo+at3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^8.0.0", + "dayjs": "^1.10.6", + "lodash.get": "^4.4.2", + "semver": "^7.6.3", + "table": "^6.7.1" + }, + "bin": { + "better-npm-audit": "index.js" + }, + "engines": { + "node": ">= 8.12" + } + }, + "node_modules/better-npm-audit/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "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, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "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, + "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/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "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 + }, + "node_modules/commander": { + "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" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", + "dev": true, + "dependencies": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + }, + "bin": { + "copyfiles": "copyfiles", + "copyup": "copyfiles" + } + }, + "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, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/copyfiles/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, + "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/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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dayjs": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/elliptic": { + "version": "6.5.7", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", + "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "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" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.11.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz", + "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==", + "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.11.1", + "@eslint/plugin-kit": "^0.2.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", + "@nodelib/fs.walk": "^1.2.8", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "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==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "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, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "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/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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "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/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", + "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "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==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.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==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hi-base32": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", + "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "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==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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 + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/js-sha256": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.11.0.tgz", + "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==" + }, + "node_modules/js-sha3": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.3.tgz", + "integrity": "sha512-BcJPCQeLg6WjEx3FE591wVAevlli8lxsxm9/FzV4HXkV49TmBH38Yvrpce6fjbADGMKFrBMGTqrVz3qPIZ88Gg==" + }, + "node_modules/js-sha512": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.9.0.tgz", + "integrity": "sha512-mirki9WS/SUahm+1TbAPkqvbCiCfOAAsyXeHxK1UkullnJVVqoJG2pL9ObvT05CN+tM7fxhfYm0NbXn+1hWoZg==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "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", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.get": { + "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==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "node_modules/loupe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lru-cache": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz", + "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/magicast": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.4.tgz", + "integrity": "sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.24.4", + "@babel/types": "^7.24.0", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/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/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "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, + "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", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/npm-run-all/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/npm-run-all/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/npm-run-all/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/npm-run-all/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm-run-all/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "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 + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "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", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/test-exclude/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/test-exclude/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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 + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz", + "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", + "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/tsx": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.1.tgz", + "integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.23.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vite": { + "version": "5.4.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz", + "integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.1.tgz", + "integrity": "sha512-N/mGckI1suG/5wQI35XeR9rsMsPqKXzq1CdUndzVstBj/HvyxxGctwnK6WX43NGt5L3Z5tcRf83g4TITKJhPrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.6", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.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" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "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, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "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, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "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, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "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/vitest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.1.tgz", + "integrity": "sha512-97We7/VC0e9X5zBVkvt7SGQMGrRtn3KtySFQG5fpaMlS+l62eeXRQO633AYhSTC3z7IMebnPPNjGXVGNRFlxBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.1", + "@vitest/mocker": "2.1.1", + "@vitest/pretty-format": "^2.1.1", + "@vitest/runner": "2.1.1", + "@vitest/snapshot": "2.1.1", + "@vitest/spy": "2.1.1", + "@vitest/utils": "2.1.1", + "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.1", + "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.1", + "@vitest/ui": "2.1.1", + "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/vlq": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", + "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..330f254 --- /dev/null +++ b/package.json @@ -0,0 +1,77 @@ +{ + "name": "@algorandfoundation/algo-ts-testing", + "version": "1.0.0", + "description": "", + "main": "index.js", + "types": "src/index.ts", + "scripts": { + "audit": "better-npm-audit audit", + "format": "prettier --write .", + "lint": "eslint \"src/**/*.ts\"", + "lint:fix": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix", + "build": "run-s build:*", + "build:0-clean": "rimraf dist coverage", + "build:1-lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" --max-warnings 10", + "build:2-check-types": "tsc -p tsconfig.json", + "build:3-build": "rollup -c --configPlugin typescript", + "build:4-copy-pkg-json": "tstk copy-package-json -c", + "build:5-copy-readme": "copyfiles ./README.md ./dist", + "watch": "rollup -c -w --configPlugin typescript", + "install-local-packages": "npm run algo-ts && npm run pyua-ts", + "algo-ts": "run-s algo-ts:*", + "algo-ts:build": "cd ../puya-ts/packages/algo-ts && npm run build", + "algo-ts:install": "npm i -D @algorandfoundation/algo-ts@../puya-ts/packages/algo-ts/dist", + "pyua-ts": "run-s pyua-ts:*", + "pyua-ts:build": "cd ../puya-ts && npm run build", + "pyua-ts:install": "npm i -D @algorandfoundation/puya-ts@../puya-ts/dist", + "xtest": "vitest run", + "xtest:coverage": "vitest run --coverage", + "xtest:ci": "vitest run --coverage --reporter junit --outputFile test-results.xml" + }, + "devDependencies": { + "@algorandfoundation/algo-ts": "file:../puya-ts/packages/algo-ts/dist", + "@algorandfoundation/algo-ts-testing": "file:./dist", + "@algorandfoundation/puya-ts": "file:../puya-ts/dist", + "@eslint/eslintrc": "3.1.0", + "@eslint/js": "9.11.1", + "@makerx/eslint-config": "4.0.0", + "@makerx/prettier-config": "2.0.1", + "@makerx/ts-toolkit": "4.0.0-beta.20", + "@rollup/plugin-commonjs": "28.0.0", + "@rollup/plugin-json": "6.1.0", + "@rollup/plugin-node-resolve": "15.3.0", + "@rollup/plugin-typescript": "^12.1.0", + "@tsconfig/node20": "20.1.4", + "@types/elliptic": "^6.4.18", + "@types/node": "22.6.1", + "@typescript-eslint/eslint-plugin": "8.7.0", + "@typescript-eslint/parser": "8.7.0", + "@vitest/coverage-v8": "2.1.1", + "better-npm-audit": "3.11.0", + "copyfiles": "2.4.1", + "eslint": "9.11.1", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "npm-run-all": "4.1.5", + "prettier": "3.3.3", + "rimraf": "6.0.1", + "rollup": "^4.22.4", + "tsx": "4.19.1", + "typescript": "^5.6.2", + "vitest": "2.1.1" + }, + "peerDependencies": { + "@algorandfoundation/algo-ts": "*", + "@algorandfoundation/puya-ts": "*", + "tslib": "^2.6.2" + }, + "dependencies": { + "@algorandfoundation/algokit-utils": "^6.2.1", + "algosdk": "^2.9.0", + "elliptic": "^6.5.7", + "js-sha256": "^0.11.0", + "js-sha3": "^0.9.3", + "js-sha512": "^0.9.0", + "tweetnacl": "^1.0.3" + } +} diff --git a/rollup.config.ts b/rollup.config.ts new file mode 100644 index 0000000..8c7c2f8 --- /dev/null +++ b/rollup.config.ts @@ -0,0 +1,38 @@ +import commonjs from '@rollup/plugin-commonjs' +import json from '@rollup/plugin-json' +import nodeResolve from '@rollup/plugin-node-resolve' +import typescript from '@rollup/plugin-typescript' +import type { RollupOptions } from 'rollup' + +const config: RollupOptions = { + input: { + index: 'src/index.ts', + 'runtime-helpers': 'src/runtime-helpers.ts', + 'test-transformer': 'src/test-transformer/index.ts', + }, + output: [ + { + dir: 'dist', + format: 'es', + exports: 'named', + entryFileNames: '[name].mjs', + preserveModules: false, + sourcemap: true, + }, + ], + treeshake: { + moduleSideEffects: false, + propertyReadSideEffects: false, + }, + external: [/node_modules/, /tslib/], + plugins: [ + typescript({ + tsconfig: 'tsconfig.build.json', + }), + commonjs(), + nodeResolve(), + json(), + ], +} + +export default config diff --git a/src/abi-metadata.ts b/src/abi-metadata.ts new file mode 100644 index 0000000..b51596f --- /dev/null +++ b/src/abi-metadata.ts @@ -0,0 +1,60 @@ +import { Contract } from '@algorandfoundation/algo-ts' +import { AbiMethodConfig, BareMethodConfig, CreateOptions, OnCompleteActionStr } from '@algorandfoundation/algo-ts/arc4' +import { DeliberateAny } from './typescript-helpers' + +export interface AbiMetadata { + methodName: string + methodSelector: string + argTypes: string[] + returnType: string + onCreate?: CreateOptions + allowActions?: OnCompleteActionStr[] +} +const AbiMetaSymbol = Symbol('AbiMetadata') +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, + }) + } +} + +export const captureMethodConfig = ( + contract: T, + methodName: string, + config?: AbiMethodConfig | BareMethodConfig, +): void => { + const metadata = ensureMetadata(contract, methodName) + metadata.onCreate = config?.onCreate ?? 'disallow' + metadata.allowActions = ([] as OnCompleteActionStr[]).concat(config?.allowActions ?? 'NoOp') +} + +const ensureMetadata = (contract: T, methodName: string): AbiMetadata => { + if (!hasAbiMetadata(contract)) { + const contractClass = contract.constructor as { new (): T } + Object.getOwnPropertyNames(Object.getPrototypeOf(contract)).forEach((name) => { + attachAbiMetadata(contractClass, name, { methodName: name, methodSelector: name, argTypes: [], returnType: '' }) + }) + } + return getAbiMetadata(contract, methodName) +} + +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 getAbiMetadata = (contract: T, methodName: string): AbiMetadata => { + 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[methodName] +} diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..c8a0742 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,37 @@ +import { Bytes } from '@algorandfoundation/algo-ts' + +export const UINT64_SIZE = 64 +export const UINT512_SIZE = 512 +export const MAX_UINT8 = 2 ** 8 - 1 +export const MAX_UINT64 = 2n ** 64n - 1n +export const MAX_UINT512 = 2n ** 512n - 1n +export const MAX_BYTES_SIZE = 4096 +export const MAX_ITEMS_IN_LOG = 32 +export const BITS_IN_BYTE = 8 +export const DEFAULT_ACCOUNT_MIN_BALANCE = 100_000 +export const DEFAULT_MAX_TXN_LIFE = 1_000 +export const DEFAULT_ASSET_CREATE_MIN_BALANCE = 1000_000 +export const DEFAULT_ASSET_OPT_IN_MIN_BALANCE = 10_000 + +// from python code: list(b"\x85Y\xb5\x14x\xfd\x89\xc1vC\xd0]\x15\xa8\xaek\x10\xabG\xbbm\x8a1\x88\x11V\xe6\xbd;\xae\x95\xd1") +export const DEFAULT_GLOBAL_GENESIS_HASH = Bytes( + new Uint8Array([ + 133, 89, 181, 20, 120, 253, 137, 193, 118, 67, 208, 93, 21, 168, 174, 107, 16, 171, 71, 187, 109, 138, 49, 136, 17, 86, 230, 189, 59, + 174, 149, 209, + ]), +) + +// algorand encoded address of 32 zero bytes +export const ZERO_ADDRESS = Bytes('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ') + +/** +"\x09" # pragma version 9 +"\x81\x01" # pushint 1 + */ +export const ALWAYS_APPROVE_TEAL_PROGRAM = Bytes(new Uint8Array([0x09, 0x81, 0x01])) + +// bytes: program (logic) data prefix when signing +export const LOGIC_DATA_PREFIX = Bytes('ProgData') + +//number: minimum transaction fee +export const MIN_TXN_FEE = 1000 diff --git a/src/context-helpers/internal-context.ts b/src/context-helpers/internal-context.ts new file mode 100644 index 0000000..0f57064 --- /dev/null +++ b/src/context-helpers/internal-context.ts @@ -0,0 +1,74 @@ +import { internal } from '@algorandfoundation/algo-ts' +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' + +/** + * For accessing implementation specific functions, with a convenient single entry + * point for other modules to import Also allows for a single place to check and + * provide. + */ +class InternalContext { + get value() { + return internal.ctxMgr.instance as TestExecutionContext + } + + get defaultSender() { + return this.value.defaultSender + } + + get ledger() { + return this.value.ledger + } + + get txn() { + return this.value.txn + } + + get contract() { + return this.value.contract + } + + get any() { + return this.value.any + } + + get activeApplication() { + return this.ledger.getApplication(this.activeGroup.activeApplicationId) + } + + get activeGroup(): TransactionGroup { + return this.value.txn.activeGroup + } + + getAccountData(accountPublicKey: internal.primitives.StubBytesCompat): AccountData { + const key = internal.primitives.BytesCls.fromCompat(accountPublicKey) + const data = this.ledger.accountDataMap.get(key.toString()) + if (!data) { + throw internal.errors.internalError('Unknown account, check correct testing context is active') + } + return data + } + + getAssetData(id: internal.primitives.StubUint64Compat): AssetData { + const key = internal.primitives.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') + } + return data + } + + getApplicationData(id: internal.primitives.StubUint64Compat): ApplicationData { + const key = internal.primitives.Uint64Cls.fromCompat(id) + const data = this.ledger.applicationDataMap.get(key.asBigInt()) + if (!data) { + throw internal.errors.internalError('Unknown application, check correct testing context is active') + } + return data + } +} + +export const lazyContext = new InternalContext() diff --git a/src/decode-logs.ts b/src/decode-logs.ts new file mode 100644 index 0000000..f7efc07 --- /dev/null +++ b/src/decode-logs.ts @@ -0,0 +1,20 @@ +import { internal } from '@algorandfoundation/algo-ts' + +export type LogDecoding = 'i' | 's' | 'b' + +export type DecodedLog = T extends 'i' ? bigint : T extends 's' ? string : Uint8Array +export type DecodedLogs = { + [Index in keyof T]: DecodedLog +} & { length: T['length'] } +export function decodeLogs(logs: Uint8Array[], decoding: T): DecodedLogs { + return logs.map((log, i) => { + switch (decoding[i]) { + case 'i': + return internal.encodingUtil.uint8ArrayToBigInt(log) + case 's': + return internal.encodingUtil.uint8ArrayToUtf8(log) + default: + return log + } + }) as DecodedLogs +} diff --git a/src/errors.ts b/src/errors.ts new file mode 100644 index 0000000..18f0378 --- /dev/null +++ b/src/errors.ts @@ -0,0 +1,17 @@ +import { internal } from '@algorandfoundation/algo-ts' + +export class NotImplementedError extends Error { + constructor(feature: string) { + super(`${feature} is not available in test context. Mock using your preferred testing framework.`) + } +} + +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) + } +} diff --git a/src/impl/account.ts b/src/impl/account.ts new file mode 100644 index 0000000..38815a0 --- /dev/null +++ b/src/impl/account.ts @@ -0,0 +1,98 @@ +import { Account, Application, Asset, bytes, internal, uint64 } from '@algorandfoundation/algo-ts' +import { DEFAULT_ACCOUNT_MIN_BALANCE, ZERO_ADDRESS } from '../constants' +import { lazyContext } from '../context-helpers/internal-context' +import { Mutable } from '../typescript-helpers' +import { asBytes, asUint64, asUint64Cls } from '../util' +import { ApplicationCls } from './application' +import { AssetCls } from './asset' + +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 Map() + optedApplications = new Map() + 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 implements Account { + readonly bytes: bytes + + constructor(address?: internal.primitives.StubBytesCompat) { + this.bytes = asBytes(address ?? ZERO_ADDRESS) + } + + private get data(): AccountData { + return lazyContext.getAccountData(this.bytes) + } + + 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(asUint64Cls(assetOrApp.id).asBigInt()) + } + if (assetOrApp instanceof ApplicationCls) { + return this.data.optedApplications.has(asUint64Cls(assetOrApp.id).asBigInt()) + } + throw new internal.errors.InternalError('Invalid argument type. Must be an `algopy.Asset` or `algopy.Application` instance.') + } +} diff --git a/src/impl/acct-params.ts b/src/impl/acct-params.ts new file mode 100644 index 0000000..dadec58 --- /dev/null +++ b/src/impl/acct-params.ts @@ -0,0 +1,73 @@ +import { Account, gtxn, internal, uint64 } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' +import { asMaybeUint64Cls } from '../util' + +export const getAccount = (acct: Account | internal.primitives.StubUint64Compat): Account => { + const acctId = asMaybeUint64Cls(acct) + if (acctId !== undefined) { + const activeTxn = lazyContext.activeGroup.activeTransaction + return (activeTxn as gtxn.ApplicationTxn).accounts(acctId.asAlgoTs()) + } + return acct as Account +} + +export const balance = (a: Account | internal.primitives.StubUint64Compat): uint64 => { + const acct = getAccount(a) + return acct.balance +} + +export const minBalance = (a: Account | internal.primitives.StubUint64Compat): uint64 => { + const acct = getAccount(a) + return acct.minBalance +} + +export const AcctParams: internal.opTypes.AcctParamsType = { + acctBalance: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.balance, acct.balance !== 0] + }, + acctMinBalance: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.minBalance, acct.balance !== 0] + }, + acctAuthAddr: function (a: Account | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + const acct = getAccount(a) + return [acct.authAddress, acct.balance !== 0] + }, + acctTotalNumUint: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.totalNumUint, acct.balance !== 0] + }, + acctTotalNumByteSlice: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.totalNumByteSlice, acct.balance !== 0] + }, + acctTotalExtraAppPages: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.totalExtraAppPages, acct.balance !== 0] + }, + acctTotalAppsCreated: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.totalAppsCreated, acct.balance !== 0] + }, + acctTotalAppsOptedIn: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.totalAppsOptedIn, acct.balance !== 0] + }, + acctTotalAssetsCreated: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.totalAssetsCreated, acct.balance !== 0] + }, + acctTotalAssets: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.totalAssets, acct.balance !== 0] + }, + acctTotalBoxes: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.totalBoxes, acct.balance !== 0] + }, + acctTotalBoxBytes: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + return [acct.totalBoxBytes, acct.balance !== 0] + }, +} diff --git a/src/impl/app-params.ts b/src/impl/app-params.ts new file mode 100644 index 0000000..e5e0361 --- /dev/null +++ b/src/impl/app-params.ts @@ -0,0 +1,63 @@ +import { Account, Application, Bytes, bytes, gtxn, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' +import { asMaybeUint64Cls, asUint64 } from '../util' + +const resolveAppIndex = (appIdOrIndex: internal.primitives.StubUint64Compat): uint64 => { + const input = asUint64(appIdOrIndex) + if (input >= 1001) { + return input + } + const txn = lazyContext.activeGroup.activeTransaction as gtxn.ApplicationTxn + return txn.apps(input).id +} + +const getApp = (app: Application | internal.primitives.StubUint64Compat): Application | undefined => { + try { + const appId = asMaybeUint64Cls(app) + if (appId !== undefined) { + return lazyContext.ledger.getApplication(resolveAppIndex(appId)) + } + return app as Application + } catch { + return undefined + } +} + +export const AppParams: internal.opTypes.AppParamsType = { + appApprovalProgram: function (a: Application | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + const app = getApp(a) + return app === undefined ? [Bytes(), false] : [app.approvalProgram, true] + }, + appClearStateProgram: function (a: Application | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + const app = getApp(a) + return app === undefined ? [Bytes(), false] : [app.clearStateProgram, true] + }, + appGlobalNumUint: function (a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const app = getApp(a) + return app === undefined ? [Uint64(0), false] : [app.globalNumUint, true] + }, + appGlobalNumByteSlice: function (a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const app = getApp(a) + return app === undefined ? [Uint64(0), false] : [app.globalNumBytes, true] + }, + appLocalNumUint: function (a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const app = getApp(a) + return app === undefined ? [Uint64(0), false] : [app.localNumUint, true] + }, + appLocalNumByteSlice: function (a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const app = getApp(a) + return app === undefined ? [Uint64(0), false] : [app.localNumBytes, true] + }, + appExtraProgramPages: function (a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const app = getApp(a) + return app === undefined ? [Uint64(0), false] : [app.extraProgramPages, true] + }, + appCreator: function (a: Application | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + const app = getApp(a) + return app === undefined ? [Account(), false] : [app.creator, true] + }, + appAddress: function (a: Application | internal.primitives.StubUint64Compat): readonly [Account, 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 new file mode 100644 index 0000000..5d72b4b --- /dev/null +++ b/src/impl/application.ts @@ -0,0 +1,69 @@ +import { Account, Application, Bytes, bytes, uint64 } from '@algorandfoundation/algo-ts' +import algosdk from 'algosdk' +import { ALWAYS_APPROVE_TEAL_PROGRAM } from '../constants' +import { lazyContext } from '../context-helpers/internal-context' +import { Mutable } from '../typescript-helpers' +import { asBigInt, asUint64 } from '../util' + +export class ApplicationData { + application: Mutable> & { appLogs: bytes[] } + 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: [], + } + } +} + +export class ApplicationCls implements Application { + readonly id: uint64 + + constructor(id?: uint64) { + this.id = 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 { + const addr = algosdk.getApplicationAddress(asBigInt(this.id)) + return Account(Bytes(addr)) + } +} diff --git a/src/impl/asset-holding.ts b/src/impl/asset-holding.ts new file mode 100644 index 0000000..0580eba --- /dev/null +++ b/src/impl/asset-holding.ts @@ -0,0 +1,41 @@ +import { Account, Asset, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' +import { asBigInt } from '../util' +import { AssetHolding as AssetHoldingData } from './account' +import { getAccount } from './acct-params' +import { getAsset } from './asset-params' + +const getAssetHolding = ( + acctOrIndex: Account | internal.primitives.StubUint64Compat, + assetOrIndex: Asset | internal.primitives.StubUint64Compat, +): AssetHoldingData | undefined => { + const account = getAccount(acctOrIndex) + const asset = getAsset(assetOrIndex) + if (asset === undefined) { + return undefined + } + + const accountData = lazyContext.getAccountData(account.bytes) + const holding = accountData.optedAssets.get(asBigInt(asset.id)) + if (holding === undefined) { + return undefined + } + return holding +} + +export const AssetHolding: internal.opTypes.AssetHoldingType = { + assetBalance: function ( + a: Account | internal.primitives.StubUint64Compat, + b: Asset | internal.primitives.StubUint64Compat, + ): readonly [uint64, boolean] { + const holding = getAssetHolding(a, b) + return holding === undefined ? [Uint64(0), false] : [holding.balance, true] + }, + assetFrozen: function ( + a: Account | internal.primitives.StubUint64Compat, + b: Asset | internal.primitives.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 new file mode 100644 index 0000000..fbc5917 --- /dev/null +++ b/src/impl/asset-params.ts @@ -0,0 +1,75 @@ +import { Account, Asset, Bytes, bytes, gtxn, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' +import { asMaybeUint64Cls, asUint64 } from '../util' + +const resolveAssetIndex = (assetIdOrIndex: internal.primitives.StubUint64Compat): uint64 => { + const input = asUint64(assetIdOrIndex) + if (input >= 1001) { + return input + } + const txn = lazyContext.activeGroup.activeTransaction as gtxn.ApplicationTxn + return txn.assets(input).id +} + +export const getAsset = (asset: Asset | internal.primitives.StubUint64Compat): Asset | undefined => { + try { + const assetId = asMaybeUint64Cls(asset) + if (assetId !== undefined) { + return lazyContext.ledger.getAsset(resolveAssetIndex(assetId)) + } + return asset as Asset + } catch { + return undefined + } +} + +export const AssetParams: internal.opTypes.AssetParamsType = { + assetTotal: function (a: Asset | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const asset = getAsset(a) + return asset === undefined ? [Uint64(0), false] : [asset.total, true] + }, + assetDecimals: function (a: Asset | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const asset = getAsset(a) + return asset === undefined ? [Uint64(0), false] : [asset.decimals, true] + }, + assetDefaultFrozen: function (a: Asset | internal.primitives.StubUint64Compat): readonly [boolean, boolean] { + const asset = getAsset(a) + return asset === undefined ? [false, false] : [asset.defaultFrozen, true] + }, + assetUnitName: function (a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + const asset = getAsset(a) + return asset === undefined ? [Bytes(), false] : [asset.unitName, true] + }, + assetName: function (a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + const asset = getAsset(a) + return asset === undefined ? [Bytes(), false] : [asset.name, true] + }, + assetUrl: function (a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + const asset = getAsset(a) + return asset === undefined ? [Bytes(), false] : [asset.url, true] + }, + assetMetadataHash: function (a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + const asset = getAsset(a) + return asset === undefined ? [Bytes(), false] : [asset.metadataHash, true] + }, + assetManager: function (a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + const asset = getAsset(a) + return asset === undefined ? [Account(), false] : [asset.manager, true] + }, + assetReserve: function (a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + const asset = getAsset(a) + return asset === undefined ? [Account(), false] : [asset.reserve, true] + }, + assetFreeze: function (a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + const asset = getAsset(a) + return asset === undefined ? [Account(), false] : [asset.freeze, true] + }, + assetClawback: function (a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + const asset = getAsset(a) + return asset === undefined ? [Account(), false] : [asset.clawback, true] + }, + assetCreator: function (a: Asset | internal.primitives.StubUint64Compat): readonly [Account, 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 new file mode 100644 index 0000000..04a94b1 --- /dev/null +++ b/src/impl/asset.ts @@ -0,0 +1,72 @@ +import { Account, Asset, bytes, internal, uint64 } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' +import { asBigInt, asUint64 } from '../util' +import { Mutable } from '../typescript-helpers' +import { AssetHolding } from './account' + +export type AssetData = Mutable> + +export class AssetCls implements Asset { + readonly id: uint64 + + constructor(id?: internal.primitives.StubUint64Compat) { + this.id = 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.bytes) + if (!accountData.optedAssets.has(asBigInt(this.id))) { + 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 accountData.optedAssets.get(asBigInt(this.id))! + } +} diff --git a/src/impl/crypto.ts b/src/impl/crypto.ts new file mode 100644 index 0000000..c9457c1 --- /dev/null +++ b/src/impl/crypto.ts @@ -0,0 +1,150 @@ +import { Bytes, bytes, internal, gtxn, arc4 } from '@algorandfoundation/algo-ts' +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 nacl from 'tweetnacl' +import { notImplementedError } from '../errors' +import { lazyContext } from '../context-helpers/internal-context' +import algosdk from 'algosdk' +import { asBytes, asBytesCls } from '../util' +import { LOGIC_DATA_PREFIX } from '../constants' + +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)) + 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)) + 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)) + 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)) + 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) + 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 => { + const txn = lazyContext.activeGroup.activeTransaction as gtxn.ApplicationTxn + const programBytes = asBytesCls( + txn.onCompletion == arc4.OnCompleteAction[arc4.OnCompleteAction.ClearState] ? txn.clearStateProgram : txn.approvalProgram, + ) + + const logicSig = new algosdk.LogicSig(programBytes.asUint8Array()) + const decodedAddress = algosdk.decodeAddress(logicSig.address()) + + const addressBytes = asBytes(decodedAddress.publicKey) + const data = LOGIC_DATA_PREFIX.concat(addressBytes).concat(asBytes(a)) + return ed25519verifyBare(data, b, c) +} + +export const ecdsaVerify = ( + v: internal.opTypes.Ecdsa, + a: internal.primitives.StubBytesCompat, + b: internal.primitives.StubBytesCompat, + c: internal.primitives.StubBytesCompat, + d: internal.primitives.StubBytesCompat, + e: internal.primitives.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 publicKey = internal.primitives.BytesCls.fromCompat(new Uint8Array([0x04])) + .concat(pubkeyXBytes) + .concat(pubkeyYBytes) + + const ecdsa = new ec(curveMap[v]) + const keyPair = ecdsa.keyFromPublic(publicKey.asUint8Array()) + return keyPair.verify(dataBytes.asUint8Array(), { r: sigRBytes.asUint8Array(), s: sigSBytes.asUint8Array() }) +} + +export const ecdsaPkRecover = ( + v: internal.opTypes.Ecdsa, + a: internal.primitives.StubBytesCompat, + b: internal.primitives.StubUint64Compat, + c: internal.primitives.StubBytesCompat, + d: internal.primitives.StubBytesCompat, +): readonly [bytes, bytes] => { + if (v !== internal.opTypes.Ecdsa.Secp256k1) { + internal.errors.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 ecdsa = new ec(curveMap[v]) + const pubKey = ecdsa.recoverPubKey( + dataBytes.asUint8Array(), + { r: rBytes.asUint8Array(), s: sBytes.asUint8Array() }, + recoveryId.asNumber(), + ) + + const x = pubKey.getX().toArray('be') + const y = pubKey.getY().toArray('be') + return [Bytes(new Uint8Array(x)), Bytes(new Uint8Array(y))] +} + +export const ecdsaPkDecompress = (v: internal.opTypes.Ecdsa, a: internal.primitives.StubBytesCompat): readonly [bytes, bytes] => { + const bytesA = internal.primitives.BytesCls.fromCompat(a) + + const ecdsa = new ec(curveMap[v]) + const keyPair = ecdsa.keyFromPublic(bytesA.asUint8Array()) + const pubKey = keyPair.getPublic() + + const x = pubKey.getX().toArray('be') + const y = pubKey.getY().toArray('be') + return [Bytes(new Uint8Array(x)), Bytes(new Uint8Array(y))] +} + +export const vrfVerify = ( + _s: internal.opTypes.VrfVerify, + _a: internal.primitives.StubBytesCompat, + _b: internal.primitives.StubBytesCompat, + _c: internal.primitives.StubBytesCompat, +): readonly [bytes, boolean] => { + notImplementedError('vrfVerify') +} + +export const EllipticCurve = new Proxy({} as internal.opTypes.EllipticCurveType, { + get: (_target, prop) => { + notImplementedError(`EllipticCurve.${prop.toString()}`) + }, +}) + +const curveMap = { + [internal.opTypes.Ecdsa.Secp256k1]: 'secp256k1', + [internal.opTypes.Ecdsa.Secp256r1]: 'p256', +} diff --git a/src/impl/global.ts b/src/impl/global.ts new file mode 100644 index 0000000..167371f --- /dev/null +++ b/src/impl/global.ts @@ -0,0 +1,190 @@ +import { Account, Application, Bytes, bytes, internal, op, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' +import { + DEFAULT_ACCOUNT_MIN_BALANCE, + DEFAULT_ASSET_CREATE_MIN_BALANCE, + DEFAULT_ASSET_OPT_IN_MIN_BALANCE, + DEFAULT_GLOBAL_GENESIS_HASH, + DEFAULT_MAX_TXN_LIFE, + MIN_TXN_FEE, + ZERO_ADDRESS, +} from '../constants' +import { asBigInt, getObjectReference } from '../util' +import algosdk from 'algosdk' + +export class GlobalData { + minTxnFee: uint64 + minBalance: uint64 + maxTxnLife: uint64 + zeroAddress: Account + logicSigVersion?: uint64 + round?: uint64 + latestTimestamp?: uint64 + groupId?: bytes + callerApplicationId: uint64 + assetCreateMinBalance: uint64 + assetOptInMinBalance: uint64 + genesisHash: bytes + opcodeBudget?: uint64 + + constructor() { + this.minTxnFee = Uint64(MIN_TXN_FEE) + this.minBalance = Uint64(DEFAULT_ACCOUNT_MIN_BALANCE) + this.maxTxnLife = Uint64(DEFAULT_MAX_TXN_LIFE) + this.zeroAddress = Account(ZERO_ADDRESS) + this.callerApplicationId = Uint64(0) + this.assetCreateMinBalance = Uint64(DEFAULT_ASSET_CREATE_MIN_BALANCE) + this.assetOptInMinBalance = Uint64(DEFAULT_ASSET_OPT_IN_MIN_BALANCE) + this.genesisHash = DEFAULT_GLOBAL_GENESIS_HASH + } +} +const getGlobalData = (): GlobalData => { + return lazyContext.ledger.globalData +} + +const getMissingValueErrorMessage = (name: keyof GlobalData) => + `'algopy.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 = { + /** + * microalgos + */ + get minTxnFee(): uint64 { + return getGlobalData().minTxnFee + }, + + /** + * microalgos + */ + get minBalance(): uint64 { + return getGlobalData().minBalance + }, + + /** + * rounds + */ + get maxTxnLife(): uint64 { + return getGlobalData().maxTxnLife + }, + + /** + * 32 byte address of all zero bytes + */ + get zeroAddress(): Account { + return getGlobalData().zeroAddress + }, + + /** + * Number of transactions in this atomic transaction group. At least 1 + */ + get groupSize(): uint64 { + const currentTransactionGroup = lazyContext.activeGroup.transactions + return Uint64(currentTransactionGroup.length) + }, + + /** + * Maximum supported version + */ + get logicSigVersion(): uint64 { + const data = getGlobalData() + if (data.logicSigVersion !== undefined) return data.logicSigVersion + throw new internal.errors.InternalError(getMissingValueErrorMessage('logicSigVersion')) + }, + + /** + * Current round number. Application mode only. + */ + get round(): uint64 { + const data = getGlobalData() + if (data.round !== undefined) return data.round + return Uint64(lazyContext.txn.groups.length + 1) + }, + + /** + * Last confirmed block UNIX timestamp. Fails if negative. Application mode only. + */ + get latestTimestamp(): uint64 { + const data = getGlobalData() + if (data.latestTimestamp !== undefined) return data.latestTimestamp + return Uint64(lazyContext.activeGroup.latestTimestamp) + }, + + /** + * ID of current application executing. Application mode only. + */ + get currentApplicationId(): Application { + return lazyContext.activeApplication + }, + + /** + * Address of the creator of the current application. Application mode only. + */ + get creatorAddress(): Account { + const app = lazyContext.activeApplication + return app.creator + }, + + /** + * Address that the current application controls. Application mode only. + */ + get currentApplicationAddress(): Account { + const appAddress = algosdk.getApplicationAddress(asBigInt(this.currentApplicationId.id)) + return Account(Bytes(appAddress)) + }, + + /** + * ID of the transaction group. 32 zero bytes if the transaction is not part of a group. + */ + get groupId(): bytes { + 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) + }, + + /** + * The remaining cost that can be spent by opcodes in this program. + */ + get opcodeBudget(): uint64 { + const data = getGlobalData() + if (data.opcodeBudget !== undefined) return data.opcodeBudget + throw new internal.errors.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. + */ + 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. + */ + get callerApplicationAddress(): Account { + const appAddress = algosdk.getApplicationAddress(asBigInt(this.callerApplicationId)) + return Account(Bytes(appAddress)) + }, + + /** + * The additional minimum balance required to create (and opt-in to) an asset. + */ + get assetCreateMinBalance(): uint64 { + return getGlobalData().assetCreateMinBalance + }, + + /** + * The additional minimum balance required to opt-in to an asset. + */ + get assetOptInMinBalance(): uint64 { + return getGlobalData().assetOptInMinBalance + }, + + /** + * The Genesis Hash for the network. + */ + get genesisHash(): bytes { + return getGlobalData().genesisHash + }, +} diff --git a/src/impl/gtxn.ts b/src/impl/gtxn.ts new file mode 100644 index 0000000..c53578a --- /dev/null +++ b/src/impl/gtxn.ts @@ -0,0 +1,219 @@ +import { Account, Application, arc4, Asset, bytes, gtxn, internal, uint64 } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' +import { asNumber, asUint64, asUint64Cls } from '../util' + +const getTransaction = (t: internal.primitives.StubUint64Compat): T => { + const transactions = lazyContext.activeGroup.transactions + const index = asNumber(t) + if (index >= transactions.length) { + throw new internal.errors.InternalError('invalid group index') + } + return transactions[index] as T +} +export const GTxn: internal.opTypes.GTxnType = { + sender(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).sender + }, + fee(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).fee + }, + firstValid(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).firstValid + }, + firstValidTime(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).firstValidTime + }, + lastValid(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).lastValid + }, + note(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).note + }, + lease(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).lease + }, + receiver(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).receiver + }, + amount(t: uint64): uint64 { + return getTransaction(t).amount + }, + closeRemainderTo(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).closeRemainderTo + }, + votePk(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).voteKey + }, + selectionPk(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).selectionKey + }, + voteFirst(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).voteFirst + }, + voteLast(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).voteLast + }, + voteKeyDilution(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).voteKeyDilution + }, + type(t: internal.primitives.StubUint64Compat): bytes { + return asUint64Cls(getTransaction(t).type).toBytes().asAlgoTs() + }, + typeEnum(t: uint64): uint64 { + return asUint64(getTransaction(t).type) + }, + xferAsset(t: internal.primitives.StubUint64Compat): Asset { + return getTransaction(t).xferAsset + }, + assetAmount(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).assetAmount + }, + assetSender(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).assetSender + }, + assetReceiver(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).assetReceiver + }, + assetCloseTo(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).assetCloseTo + }, + groupIndex(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).groupIndex + }, + txId(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).txnId + }, + applicationId(t: internal.primitives.StubUint64Compat): Application { + return getTransaction(t).appId + }, + onCompletion(t: internal.primitives.StubUint64Compat): uint64 { + const onCompletionStr = getTransaction(t).onCompletion + return asUint64(arc4.OnCompleteAction[onCompletionStr]) + }, + applicationArgs(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { + return getTransaction(a).appArgs(asUint64(b)) + }, + numAppArgs(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).numAppArgs + }, + accounts(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Account { + return getTransaction(a).accounts(asUint64(b)) + }, + numAccounts(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).numAccounts + }, + approvalProgram(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).approvalProgram + }, + clearStateProgram(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).clearStateProgram + }, + rekeyTo(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).rekeyTo + }, + configAsset(t: internal.primitives.StubUint64Compat): Asset { + return getTransaction(t).configAsset + }, + configAssetTotal(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).total + }, + configAssetDecimals(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).decimals + }, + configAssetDefaultFrozen(t: internal.primitives.StubUint64Compat): boolean { + return getTransaction(t).defaultFrozen + }, + configAssetUnitName(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).unitName + }, + configAssetName(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).assetName + }, + configAssetUrl(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).url + }, + configAssetMetadataHash(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).metadataHash + }, + configAssetManager(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).manager + }, + configAssetReserve(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).reserve + }, + configAssetFreeze(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).freeze + }, + configAssetClawback(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).clawback + }, + freezeAsset(t: internal.primitives.StubUint64Compat): Asset { + return getTransaction(t).freezeAsset + }, + freezeAssetAccount(t: internal.primitives.StubUint64Compat): Account { + return getTransaction(t).freezeAccount + }, + freezeAssetFrozen(t: internal.primitives.StubUint64Compat): boolean { + return getTransaction(t).frozen + }, + assets(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Asset { + return getTransaction(a).assets(asUint64(b)) + }, + numAssets(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).numAssets + }, + applications(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Application { + return getTransaction(a).apps(asUint64(b)) + }, + numApplications(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).numApps + }, + globalNumUint(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).globalNumUint + }, + globalNumByteSlice(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).globalNumBytes + }, + localNumUint(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).localNumUint + }, + localNumByteSlice(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).localNumBytes + }, + extraProgramPages(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).extraProgramPages + }, + nonparticipation(t: internal.primitives.StubUint64Compat): boolean { + return getTransaction(t).nonparticipation + }, + logs(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { + return getTransaction(a).logs(asUint64(b)) + }, + numLogs(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).numLogs + }, + createdAssetId(t: internal.primitives.StubUint64Compat): Asset { + return getTransaction(t).createdAsset + }, + createdApplicationId(t: internal.primitives.StubUint64Compat): Application { + return getTransaction(t).createdApp + }, + lastLog(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).lastLog + }, + stateProofPk(t: internal.primitives.StubUint64Compat): bytes { + return getTransaction(t).stateProofKey + }, + approvalProgramPages(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { + return getTransaction(a).approvalProgramPages(asUint64(b)) + }, + numApprovalProgramPages(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).numApprovalProgramPages + }, + clearStateProgramPages(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { + return getTransaction(a).clearStateProgramPages(asUint64(b)) + }, + numClearStateProgramPages(t: internal.primitives.StubUint64Compat): uint64 { + return getTransaction(t).numClearStateProgramPages + }, +} diff --git a/src/impl/index.ts b/src/impl/index.ts new file mode 100644 index 0000000..531347d --- /dev/null +++ b/src/impl/index.ts @@ -0,0 +1,9 @@ +export { AcctParams, balance, minBalance } from './acct-params' +export { AppParams } from './app-params' +export { AssetHolding } from './asset-holding' +export { AssetParams } from './asset-params' +export * from './crypto' +export { Global } from './global' +export { GTxn } from './gtxn' +export * from './pure' +export { Txn, gaid } from './txn' diff --git a/src/impl/pure.ts b/src/impl/pure.ts new file mode 100644 index 0000000..0d1ce58 --- /dev/null +++ b/src/impl/pure.ts @@ -0,0 +1,376 @@ +import { biguint, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT64, MAX_UINT8, UINT64_SIZE } from '../constants' +import { notImplementedError } from '../errors' +import { asBigUint, asBytes, asMaybeBytesCls, asMaybeUint64Cls, asUint64Cls, binaryStringToBytes } from '../util' + +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) + const sum = uint64A.asBigInt() + uint64B.asBigInt() + return toUint128(sum) +} + +export const base64Decode = (e: internal.opTypes.Base64, a: internal.primitives.StubBytesCompat): bytes => { + const encoding = e === internal.opTypes.Base64.StdEncoding ? 'base64' : 'base64url' + const bytesValue = internal.primitives.BytesCls.fromCompat(a) + const stringValue = bytesValue.toString() + + const bufferResult = Buffer.from(stringValue, encoding) + if (bufferResult.toString(encoding) !== stringValue) { + internal.errors.avmError('illegal base64 data') + } + + const uint8ArrayResult = new Uint8Array(bufferResult) + return asBytes(uint8ArrayResult) +} + +export const bitLength = (a: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat): uint64 => { + const uint64Cls = asMaybeUint64Cls(a) + const bigUintCls = asMaybeBytesCls(a)?.toBigUint() + const bigIntValue = (uint64Cls?.asBigInt() ?? bigUintCls?.asBigInt())! + const binaryValue = bigIntValue === 0n ? '' : bigIntValue.toString(2) + 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()) + const sqrtValue = squareroot(bigintValue) + return asBigUint(sqrtValue) +} + +export const btoi = (a: internal.primitives.StubBytesCompat): uint64 => { + const bytesValue = internal.primitives.BytesCls.fromCompat(a) + if (bytesValue.length.asAlgoTs() > BITS_IN_BYTE) { + internal.errors.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() + if (size > MAX_BYTES_SIZE) { + internal.errors.avmError('bzero attempted to create a too large string') + } + return Bytes(new Uint8Array(Array(Number(size)).fill(0x00))) +} + +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) + return bytesA.concat(bytesB).asAlgoTs() +} + +export const divmodw = ( + a: internal.primitives.StubUint64Compat, + b: internal.primitives.StubUint64Compat, + c: internal.primitives.StubUint64Compat, + d: internal.primitives.StubUint64Compat, +): readonly [uint64, uint64, uint64, uint64] => { + const i = uint128ToBigInt(a, b) + const j = uint128ToBigInt(c, d) + + const div = i / j + const mod = i % j + return [...toUint128(div), ...toUint128(mod)] +} + +export const divw = ( + a: internal.primitives.StubUint64Compat, + b: internal.primitives.StubUint64Compat, + c: internal.primitives.StubUint64Compat, +): uint64 => { + const i = uint128ToBigInt(a, b) + const j = internal.primitives.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() + if (base === 0n && exponent === 0n) { + throw internal.errors.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() + if (base === 0n && exponent === 0n) { + throw internal.errors.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) + 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 + } + + if (start > bytesLength) { + internal.errors.codeError(`extraction start ${start} is beyond length`) + } + if (end > bytesLength) { + internal.errors.codeError(`extraction end ${end} is beyond length`) + } + + return bytesValue.slice(start, end).asAlgoTs() +} + +export const extractUint16 = (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): uint64 => { + const result = extract(a, b, 2) + const bytesResult = internal.primitives.BytesCls.fromCompat(result) + return bytesResult.toUint64().asAlgoTs() +} + +export const extractUint32 = (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): uint64 => { + const result = extract(a, b, 4) + const bytesResult = internal.primitives.BytesCls.fromCompat(result) + return bytesResult.toUint64().asAlgoTs() +} + +export const extractUint64 = (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): uint64 => { + const result = extract(a, b, 8) + const bytesResult = internal.primitives.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(a) + const index = internal.primitives.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`) + } + return binaryString[adjustedIndex] === '1' ? Uint64(1) : Uint64(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() + if (index >= bytesValue.length.asNumber()) { + internal.errors.codeError(`getBytes index ${index} is beyond length`) + } + return bytesValue.at(index).toUint64().asAlgoTs() +} + +export const itob = (a: internal.primitives.StubUint64Compat): bytes => { + return asUint64Cls(a).toBytes().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) + 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) + + const valueLength = bytesValue.length.asNumber() + const replacementLength = replacement.length.asNumber() + + if (index + replacementLength > valueLength) { + internal.errors.codeError(`expected value <= ${valueLength}, got: ${index + replacementLength}`) + } + return bytesValue + .slice(0, index) + .concat(replacement) + .concat(bytesValue.slice(index + replacementLength, valueLength)) + .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) +export const select = (( + a: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, + b: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, + c: internal.primitives.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() + + 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, +) => { + const uint64Cls = asMaybeUint64Cls(a) + const bytesCls = asMaybeBytesCls(a) + const binaryString = toBinaryString((uint64Cls ?? bytesCls)!) + + const isUint64 = !!uint64Cls + const indexFromLeft = internal.primitives.Uint64Cls.fromCompat(b).asNumber() + const indexFromRight = binaryString.length - indexFromLeft - 1 + const bit = internal.primitives.Uint64Cls.fromCompat(c).asNumber() + + const newBytes = doSetBit(binaryString, isUint64 ? indexFromRight : indexFromLeft, bit) + return isUint64 ? newBytes.toUint64().asAlgoTs() : newBytes.asAlgoTs() +}) as SetBitType + +export const setByte = ( + a: internal.primitives.StubBytesCompat, + b: internal.primitives.StubUint64Compat, + c: internal.primitives.StubUint64Compat, +): bytes => { + const binaryString = toBinaryString(a) + + const byteIndex = internal.primitives.Uint64Cls.fromCompat(b).asNumber() + const bitIndex = byteIndex * BITS_IN_BYTE + + const replacementNumber = internal.primitives.Uint64Cls.fromCompat(c).asBigInt() + const replacement = replacementNumber === 0n ? '0'.repeat(BITS_IN_BYTE) : toBinaryString(c, true) + + if (bitIndex >= binaryString.length) { + internal.errors.codeError(`setByte index ${byteIndex} is beyond length`) + } + if (replacementNumber > MAX_UINT8) { + internal.errors.codeError(`setByte value ${replacementNumber} > ${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) + const bigIntA = uint64A.asBigInt() + const bigIntB = uint64B.asBigInt() + if (bigIntB >= UINT64_SIZE) { + internal.errors.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) + const bigIntA = uint64A.asBigInt() + const bigIntB = uint64B.asBigInt() + if (bigIntB >= UINT64_SIZE) { + internal.errors.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() + 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() + if (start > end) { + internal.errors.codeError('substring end before start') + } + if (end > bytesValue.length.asNumber()) { + internal.errors.codeError('substring range beyond length of string') + } + return bytesValue.slice(start, end).asAlgoTs() +} + +export const JsonRef = new Proxy({} as internal.opTypes.JsonRefType, { + get: (_target, prop) => { + notImplementedError(`JsonRef.${prop.toString()}`) + }, +}) + +const squareroot = (x: bigint): bigint => { + let lo = 0n, + hi = x + while (lo <= hi) { + const mid = (lo + hi) / 2n + if (mid * mid > x) hi = mid - 1n + else lo = mid + 1n + } + return hi +} + +const toUint128 = (value: bigint): [uint64, uint64] => { + const cf = value >> 64n + const rest = value & MAX_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() + return (bigIntA << 64n) + bigIntB +} + +const toBinaryString = (a: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, isDynamic = false): string => { + const uint64Cls = asMaybeUint64Cls(a) + const bytesCls = asMaybeBytesCls(a) + let binaryString: string = '' + if (uint64Cls) { + binaryString = [...uint64Cls.toBytes(isDynamic).asUint8Array()].map((x) => x.toString(2).padStart(BITS_IN_BYTE, '0')).join('') + } else if (bytesCls) { + binaryString = [...bytesCls.asUint8Array()].map((x) => x.toString(2).padStart(BITS_IN_BYTE, '0')).join('') + } else { + internal.errors.codeError('unknown type for argument a') + } + return binaryString +} + +const doSetBit = (binaryString: string, index: number, bit: number): internal.primitives.BytesCls => { + if (index < 0 || index >= binaryString.length) { + internal.errors.codeError(`setBit index ${index < 0 ? binaryString.length - index : index} is beyond length`) + } + if (bit !== 0 && bit !== 1) { + internal.errors.codeError(`setBit value > 1`) + } + const updatedString = binaryString.slice(0, index) + bit.toString() + binaryString.slice(index + 1) + return binaryStringToBytes(updatedString) +} diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts new file mode 100644 index 0000000..efacbf2 --- /dev/null +++ b/src/impl/transactions.ts @@ -0,0 +1,313 @@ +import { Account, Application, Asset, bytes, Bytes, gtxn, internal, TransactionType, uint64, Uint64 } from '@algorandfoundation/algo-ts' +import { OnCompleteActionStr } from '@algorandfoundation/algo-ts/arc4' +import { MAX_ITEMS_IN_LOG } from '../constants' +import { lazyContext } from '../context-helpers/internal-context' +import { Mutable, ObjectKeys } from '../typescript-helpers' +import { asBytes, asNumber, getRandomBytes } from '../util' + +const baseDefaultFields = () => ({ + sender: lazyContext.defaultSender, + fee: Uint64(0), + firstValid: Uint64(0), + firstValidTime: Uint64(0), + lastValid: Uint64(0), + note: Bytes(), + lease: Bytes(), + typeBytes: Bytes(), + groupIndex: Uint64(0), + txnId: getRandomBytes(32).asAlgoTs(), + rekeyTo: Account(), +}) + +export type TxnFields = Partial>>> + +abstract class TransactionBase { + protected constructor(fields: Partial>) { + const baseDefaults = baseDefaultFields() + this.sender = fields.sender ?? baseDefaults.sender + this.fee = fields.fee ?? baseDefaults.fee + this.firstValid = fields.firstValid ?? baseDefaults.firstValid + this.firstValidTime = fields.firstValidTime ?? baseDefaults.firstValidTime + this.lastValid = fields.lastValid ?? baseDefaults.lastValid + this.note = fields.note ?? baseDefaults.note + this.lease = fields.lease ?? baseDefaults.lease + this.typeBytes = fields.typeBytes ?? baseDefaults.typeBytes + this.groupIndex = fields.groupIndex ?? baseDefaults.groupIndex + this.txnId = fields.txnId ?? baseDefaults.txnId + this.rekeyTo = fields.rekeyTo ?? baseDefaults.rekeyTo + } + + readonly sender: Account + readonly fee: uint64 + readonly firstValid: uint64 + readonly firstValidTime: uint64 + readonly lastValid: uint64 + readonly note: bytes + readonly lease: bytes + readonly typeBytes: bytes + readonly groupIndex: uint64 + readonly txnId: bytes + readonly rekeyTo: Account +} + +export class PaymentTransaction extends TransactionBase implements gtxn.PaymentTxn { + /* @internal */ + static create(fields: TxnFields) { + return new PaymentTransaction(fields) + } + + private constructor(fields: TxnFields) { + super(fields) + this.receiver = fields.receiver ?? Account() + this.amount = fields.amount ?? Uint64(0) + this.closeRemainderTo = fields.closeRemainderTo ?? Account() + } + + readonly receiver: Account + readonly amount: uint64 + readonly closeRemainderTo: Account + readonly type: TransactionType.Payment = TransactionType.Payment +} + +export class KeyRegistrationTransaction extends TransactionBase implements gtxn.KeyRegistrationTxn { + /* @internal */ + static create(fields: TxnFields) { + return new KeyRegistrationTransaction(fields) + } + + private constructor(fields: TxnFields) { + super(fields) + this.voteKey = fields.voteKey ?? Bytes() + this.selectionKey = fields.selectionKey ?? Bytes() + this.voteFirst = fields.voteFirst ?? Uint64(0) + this.voteLast = fields.voteLast ?? Uint64(0) + this.voteKeyDilution = fields.voteKeyDilution ?? Uint64(0) + this.nonparticipation = fields.nonparticipation ?? false + this.stateProofKey = fields.stateProofKey ?? Bytes() + } + + readonly voteKey: bytes + readonly selectionKey: bytes + readonly voteFirst: uint64 + readonly voteLast: uint64 + readonly voteKeyDilution: uint64 + readonly nonparticipation: boolean + readonly stateProofKey: bytes + readonly type: TransactionType.KeyRegistration = TransactionType.KeyRegistration +} + +export class AssetConfigTransaction extends TransactionBase implements gtxn.AssetConfigTxn { + /* @internal */ + static create(fields: TxnFields) { + return new AssetConfigTransaction(fields) + } + + private constructor(fields: TxnFields) { + super(fields) + this.configAsset = fields.configAsset ?? Asset() + this.total = fields.total ?? Uint64(0) + this.decimals = fields.decimals ?? Uint64(0) + this.defaultFrozen = fields.defaultFrozen ?? false + this.unitName = fields.unitName ?? Bytes() + this.assetName = fields.assetName ?? Bytes() + this.url = fields.url ?? Bytes() + this.metadataHash = fields.metadataHash ?? Bytes() + this.manager = fields.manager ?? Account() + this.reserve = fields.reserve ?? Account() + this.freeze = fields.freeze ?? Account() + this.clawback = fields.clawback ?? Account() + this.createdAsset = fields.createdAsset ?? Asset() + } + + readonly configAsset: Asset + readonly total: uint64 + readonly decimals: uint64 + readonly defaultFrozen: boolean + readonly unitName: bytes + 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 type: TransactionType.AssetConfig = TransactionType.AssetConfig +} + +export class AssetTransferTransaction extends TransactionBase implements gtxn.AssetTransferTxn { + /* @internal */ + static create(fields: TxnFields) { + return new AssetTransferTransaction(fields) + } + + private constructor(fields: TxnFields) { + super(fields) + this.xferAsset = fields.xferAsset ?? Asset() + this.assetAmount = fields.assetAmount ?? Uint64(0) + this.assetSender = fields.assetSender ?? Account() + this.assetReceiver = fields.assetReceiver ?? Account() + this.assetCloseTo = fields.assetCloseTo ?? Account() + } + + readonly xferAsset: Asset + readonly assetAmount: uint64 + readonly assetSender: Account + readonly assetReceiver: Account + readonly assetCloseTo: Account + + readonly type: TransactionType.AssetTransfer = TransactionType.AssetTransfer +} + +export class AssetFreezeTransaction extends TransactionBase implements gtxn.AssetFreezeTxn { + /* @internal */ + static create(fields: TxnFields) { + return new AssetFreezeTransaction(fields) + } + + private constructor(fields: TxnFields) { + super(fields) + this.freezeAsset = fields.freezeAsset ?? Asset() + this.freezeAccount = fields.freezeAccount ?? Account() + this.frozen = fields.frozen ?? false + } + + readonly freezeAsset: Asset + readonly freezeAccount: Account + readonly frozen: boolean + + readonly type: TransactionType.AssetFreeze = TransactionType.AssetFreeze +} + +export type ApplicationTransactionFields = TxnFields & + Partial<{ + appArgs: Array + accounts: Array + assets: Array + apps: Array + approvalProgramPages: Array + clearStateProgramPages: Array + appLogs: Array + }> + +export class ApplicationTransaction extends TransactionBase implements gtxn.ApplicationTxn { + /* @internal */ + static create(fields: ApplicationTransactionFields) { + return new ApplicationTransaction(fields) + } + #appArgs: Array + #accounts: Array + #assets: Array + #apps: Array + #approvalProgramPages: Array + #clearStateProgramPages: Array + #appLogs: Array + + private constructor(fields: ApplicationTransactionFields) { + super(fields) + this.appId = fields.appId ?? Application() + this.onCompletion = fields.onCompletion ?? 'NoOp' + this.globalNumUint = fields.globalNumUint ?? Uint64(0) + this.globalNumBytes = fields.globalNumBytes ?? Uint64(0) + this.localNumUint = fields.localNumUint ?? Uint64(0) + this.localNumBytes = fields.localNumBytes ?? Uint64(0) + this.extraProgramPages = fields.extraProgramPages ?? Uint64(0) + this.createdApp = fields.createdApp ?? Application() + this.#appArgs = fields.appArgs ?? [] + this.#appLogs = fields.appLogs ?? [] + this.#accounts = fields.accounts ?? [] + this.#assets = fields.assets ?? [] + this.#apps = fields.apps ?? [] + this.#approvalProgramPages = fields.approvalProgramPages ?? (fields.approvalProgram ? [fields.approvalProgram] : []) + this.#clearStateProgramPages = fields.clearStateProgramPages ?? (fields.clearStateProgram ? [fields.clearStateProgram] : []) + } + + readonly appId: Application + readonly onCompletion: OnCompleteActionStr + readonly globalNumUint: uint64 + readonly globalNumBytes: uint64 + readonly localNumUint: uint64 + readonly localNumBytes: uint64 + readonly extraProgramPages: uint64 + readonly createdApp: Application + get approvalProgram() { + return this.approvalProgramPages(0) + } + get clearStateProgram() { + return this.clearStateProgramPages(0) + } + get numAppArgs() { + return Uint64(this.#appArgs.length) + } + get numAccounts() { + return Uint64(this.#accounts.length) + } + get numAssets() { + return Uint64(this.#assets.length) + } + get numApps() { + return Uint64(this.#apps.length) + } + get numApprovalProgramPages() { + return Uint64(this.#approvalProgramPages.length) + } + get numClearStateProgramPages() { + return Uint64(this.#clearStateProgramPages.length) + } + get numLogs() { + return Uint64(this.#appLogs.length || lazyContext.getApplicationData(this.appId.id).appLogs.length) + } + get lastLog() { + return this.#appLogs.at(-1) ?? lazyContext.getApplicationData(this.appId.id).appLogs.at(-1) ?? Bytes() + } + appArgs(index: internal.primitives.StubUint64Compat): bytes { + return this.#appArgs[asNumber(index)] + } + accounts(index: internal.primitives.StubUint64Compat): Account { + return this.#accounts[asNumber(index)] + } + assets(index: internal.primitives.StubUint64Compat): Asset { + return this.#assets[asNumber(index)] + } + apps(index: internal.primitives.StubUint64Compat): Application { + return this.#apps[asNumber(index)] + } + approvalProgramPages(index: internal.primitives.StubUint64Compat): bytes { + return this.#approvalProgramPages[asNumber(index)] + } + clearStateProgramPages(index: internal.primitives.StubUint64Compat): bytes { + return this.#clearStateProgramPages[asNumber(index)] + } + logs(index: internal.primitives.StubUint64Compat): bytes { + const i = asNumber(index) + return this.#appLogs[i] ?? lazyContext.getApplicationData(this.appId.id).appLogs ?? Bytes() + } + readonly type: TransactionType.ApplicationCall = TransactionType.ApplicationCall + + /* @internal */ + get appLogs() { + return this.#appLogs + } + /* @internal */ + appendLog(value: internal.primitives.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`) + } + this.#appLogs.push(asBytes(value)) + } +} + +export type Transaction = + | PaymentTransaction + | KeyRegistrationTransaction + | AssetConfigTransaction + | AssetTransferTransaction + | AssetFreezeTransaction + | ApplicationTransaction + +export type AllTransactionFields = TxnFields & + TxnFields & + TxnFields & + TxnFields & + TxnFields & + ApplicationTransactionFields diff --git a/src/impl/txn.ts b/src/impl/txn.ts new file mode 100644 index 0000000..6d8c434 --- /dev/null +++ b/src/impl/txn.ts @@ -0,0 +1,495 @@ +import { Account, Application, arc4, Asset, bytes, gtxn, internal, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' +import { asNumber, asUint64, asUint64Cls } from '../util' + +const getActiveTransaction = (): T => { + return lazyContext.activeGroup.activeTransaction as T +} + +export const gaid = (a: internal.primitives.StubUint64Compat): uint64 => { + const group = lazyContext.activeGroup + const transaction = group.transactions[asNumber(a)] + if (transaction.type === TransactionType.ApplicationCall) { + return transaction.createdApp.id + } 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`) + } +} + +export const Txn: internal.opTypes.TxnType = { + get sender(): Account { + return getActiveTransaction().sender + }, + + /** + * microalgos + */ + get fee(): uint64 { + return getActiveTransaction().fee + }, + + /** + * round number + */ + get firstValid(): uint64 { + return getActiveTransaction().firstValid + }, + + /** + * UNIX timestamp of block before txn.FirstValid. Fails if negative + */ + get firstValidTime(): uint64 { + return getActiveTransaction().firstValidTime + }, + + /** + * round number + */ + get lastValid(): uint64 { + return getActiveTransaction().lastValid + }, + + /** + * Any data up to 1024 bytes + */ + get note(): bytes { + return getActiveTransaction().note + }, + + /** + * 32 byte lease value + */ + get lease(): bytes { + return getActiveTransaction().lease + }, + + /** + * 32 byte address + */ + get receiver(): Account { + return getActiveTransaction().receiver + }, + + /** + * microalgos + */ + get amount(): uint64 { + return getActiveTransaction().amount + }, + + /** + * 32 byte address + */ + get closeRemainderTo(): Account { + return getActiveTransaction().closeRemainderTo + }, + + /** + * 32 byte address + */ + get votePk(): bytes { + return getActiveTransaction().voteKey + }, + + /** + * 32 byte address + */ + get selectionPk(): bytes { + return getActiveTransaction().selectionKey + }, + + /** + * The first round that the participation key is valid. + */ + get voteFirst(): uint64 { + return getActiveTransaction().voteFirst + }, + + /** + * The last round that the participation key is valid. + */ + get voteLast(): uint64 { + return getActiveTransaction().voteLast + }, + + /** + * Dilution for the 2-level participation key + */ + get voteKeyDilution(): uint64 { + return getActiveTransaction().voteKeyDilution + }, + + /** + * Transaction type as bytes + */ + get type(): bytes { + return asUint64Cls(getActiveTransaction().type).toBytes().asAlgoTs() + }, + + /** + * Transaction type as integer + */ + get typeEnum(): uint64 { + return asUint64(getActiveTransaction().type) + }, + + /** + * Asset ID + */ + get xferAsset(): Asset { + return getActiveTransaction().xferAsset + }, + + /** + * value in Asset's units + */ + get assetAmount(): uint64 { + return getActiveTransaction().assetAmount + }, + + /** + * 32 byte address. Source of assets if Sender is the Asset's Clawback address. + */ + get assetSender(): Account { + return getActiveTransaction().assetSender + }, + + /** + * 32 byte address + */ + get assetReceiver(): Account { + return getActiveTransaction().assetReceiver + }, + + /** + * 32 byte address + */ + get assetCloseTo(): Account { + return getActiveTransaction().assetCloseTo + }, + + /** + * Position of this transaction within an atomic transaction group. A stand-alone transaction is implicitly element 0 in a group of 1 + */ + get groupIndex(): uint64 { + return getActiveTransaction().groupIndex + }, + + /** + * The computed ID for this transaction. 32 bytes. + */ + get txId(): bytes { + return getActiveTransaction().txnId + }, + + /** + * ApplicationID from ApplicationCall transaction + */ + get applicationId(): Application { + return getActiveTransaction().appId + }, + + /** + * ApplicationCall transaction on completion action + */ + get onCompletion(): uint64 { + const onCompletionStr = getActiveTransaction().onCompletion + return asUint64(arc4.OnCompleteAction[onCompletionStr]) + }, + + /** + * Arguments passed to the application in the ApplicationCall transaction + */ + applicationArgs(a: internal.primitives.StubUint64Compat): bytes { + return getActiveTransaction().appArgs(asUint64(a)) + }, + + /** + * Number of ApplicationArgs + */ + get numAppArgs(): uint64 { + return getActiveTransaction().numAppArgs + }, + + /** + * Accounts listed in the ApplicationCall transaction + */ + accounts(a: internal.primitives.StubUint64Compat): Account { + return getActiveTransaction().accounts(asUint64(a)) + }, + + /** + * Number of Accounts + */ + get numAccounts(): uint64 { + return getActiveTransaction().numAccounts + }, + + /** + * Approval program + */ + get approvalProgram(): bytes { + return getActiveTransaction().approvalProgram + }, + + /** + * Clear state program + */ + get clearStateProgram(): bytes { + return getActiveTransaction().clearStateProgram + }, + + /** + * 32 byte Sender's new AuthAddr + */ + get rekeyTo(): Account { + return getActiveTransaction().rekeyTo + }, + + /** + * Asset ID in asset config transaction + */ + get configAsset(): Asset { + return getActiveTransaction().configAsset + }, + + /** + * Total number of units of this asset created + */ + get configAssetTotal(): uint64 { + return getActiveTransaction().total + }, + + /** + * Number of digits to display after the decimal place when displaying the asset + */ + get configAssetDecimals(): uint64 { + return getActiveTransaction().decimals + }, + + /** + * Whether the asset's slots are frozen by default or not, 0 or 1 + */ + get configAssetDefaultFrozen(): boolean { + return getActiveTransaction().defaultFrozen + }, + + /** + * Unit name of the asset + */ + get configAssetUnitName(): bytes { + return getActiveTransaction().unitName + }, + + /** + * The asset name + */ + get configAssetName(): bytes { + return getActiveTransaction().assetName + }, + + /** + * URL + */ + get configAssetUrl(): bytes { + return getActiveTransaction().url + }, + + /** + * 32 byte commitment to unspecified asset metadata + */ + get configAssetMetadataHash(): bytes { + return getActiveTransaction().metadataHash + }, + + /** + * 32 byte address + */ + get configAssetManager(): Account { + return getActiveTransaction().manager + }, + + /** + * 32 byte address + */ + get configAssetReserve(): Account { + return getActiveTransaction().reserve + }, + + /** + * 32 byte address + */ + get configAssetFreeze(): Account { + return getActiveTransaction().freeze + }, + + /** + * 32 byte address + */ + get configAssetClawback(): Account { + return getActiveTransaction().clawback + }, + + /** + * Asset ID being frozen or un-frozen + */ + get freezeAsset(): Asset { + return getActiveTransaction().freezeAsset + }, + + /** + * 32 byte address of the account whose asset slot is being frozen or un-frozen + */ + get freezeAssetAccount(): Account { + return getActiveTransaction().freezeAccount + }, + + /** + * The new frozen value, 0 or 1 + */ + get freezeAssetFrozen(): boolean { + return getActiveTransaction().frozen + }, + + /** + * Foreign Assets listed in the ApplicationCall transaction + */ + assets(a: internal.primitives.StubUint64Compat): Asset { + return getActiveTransaction().assets(asUint64(a)) + }, + + /** + * Number of Assets + */ + get numAssets(): uint64 { + return getActiveTransaction().numAssets + }, + + /** + * Foreign Apps listed in the ApplicationCall transaction + */ + applications(a: internal.primitives.StubUint64Compat): Application { + return getActiveTransaction().apps(asUint64(a)) + }, + + /** + * Number of Applications + */ + get numApplications(): uint64 { + return getActiveTransaction().numApps + }, + + /** + * Number of global state integers in ApplicationCall + */ + get globalNumUint(): uint64 { + return getActiveTransaction().globalNumUint + }, + + /** + * Number of global state byteslices in ApplicationCall + */ + get globalNumByteSlice(): uint64 { + return getActiveTransaction().globalNumBytes + }, + + /** + * Number of local state integers in ApplicationCall + */ + get localNumUint(): uint64 { + return getActiveTransaction().localNumUint + }, + + /** + * Number of local state byteslices in ApplicationCall + */ + get localNumByteSlice(): uint64 { + return getActiveTransaction().localNumBytes + }, + + /** + * Number of additional pages for each of the application's approval and clear state programs. An ExtraProgramPages of 1 means 2048 more total bytes, or 1024 for each program. + */ + get extraProgramPages(): uint64 { + return getActiveTransaction().extraProgramPages + }, + + /** + * Marks an account nonparticipating for rewards + */ + get nonparticipation(): boolean { + return getActiveTransaction().nonparticipation + }, + + /** + * Log messages emitted by an application call (only with `itxn` in v5). Application mode only + */ + logs(a: internal.primitives.StubUint64Compat): bytes { + return getActiveTransaction().logs(asUint64(a)) + }, + + /** + * Number of Logs (only with `itxn` in v5). Application mode only + */ + get numLogs(): uint64 { + return getActiveTransaction().numLogs + }, + + /** + * Asset ID allocated by the creation of an ASA (only with `itxn` in v5). Application mode only + */ + get createdAssetId(): Asset { + return getActiveTransaction().createdAsset + }, + + /** + * ApplicationID allocated by the creation of an application (only with `itxn` in v5). Application mode only + */ + get createdApplicationId(): Application { + return getActiveTransaction().createdApp + }, + + /** + * The last message emitted. Empty bytes if none were emitted. Application mode only + */ + get lastLog(): bytes { + return getActiveTransaction().lastLog + }, + + /** + * 64 byte state proof public key + */ + get stateProofPk(): bytes { + return getActiveTransaction().stateProofKey + }, + + /** + * Approval Program as an array of pages + */ + approvalProgramPages(a: internal.primitives.StubUint64Compat): bytes { + return getActiveTransaction().approvalProgramPages(asUint64(a)) + }, + + /** + * Number of Approval Program pages + */ + get numApprovalProgramPages(): uint64 { + return getActiveTransaction().numApprovalProgramPages + }, + + /** + * ClearState Program as an array of pages + */ + clearStateProgramPages(a: internal.primitives.StubUint64Compat): bytes { + return getActiveTransaction().clearStateProgramPages(asUint64(a)) + }, + + /** + * Number of ClearState Program pages + */ + get numClearStateProgramPages(): uint64 { + return getActiveTransaction().numClearStateProgramPages + }, +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..9d9b0b8 --- /dev/null +++ b/src/index.ts @@ -0,0 +1 @@ +export { TestExecutionContext } from './test-execution-context' diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts new file mode 100644 index 0000000..2cd0f11 --- /dev/null +++ b/src/runtime-helpers.ts @@ -0,0 +1,283 @@ +import { internal } from '@algorandfoundation/algo-ts' +import { MAX_UINT64 } from './constants' +import { DeliberateAny } from './typescript-helpers' +import { nameOfType } from './util' +export { attachAbiMetadata } from './abi-metadata' + +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`) +} +// export function wrapLiteral(x: unknown) { +// if (typeof x === 'boolean') return x +// if (isBytes(x)) return makeBytes(x) +// if (isUint64(x)) return makeUint64(x) +// internalError(`Cannot wrap ${nameOfType(x)}`) +// } + +type BinaryOps = '+' | '-' | '*' | '**' | '/' | '%' | '>' | '>=' | '<' | '<=' | '===' | '!==' | '<<' | '>>' | '&' | '|' | '^' +type UnaryOps = '~' + +function tryGetBigInt(value: unknown): bigint | undefined { + if (typeof value == 'bigint') return value + if (typeof value == 'number') return BigInt(value) + if (value instanceof internal.primitives.Uint64Cls) return value.value + if (value instanceof internal.primitives.BigUintCls) return value.value + return undefined +} + +export function binaryOp(left: unknown, right: unknown, op: BinaryOps) { + if (left instanceof internal.primitives.BigUintCls || right instanceof internal.primitives.BigUintCls) { + return bigUintBinaryOp(left, right, op) + } + if (left instanceof internal.primitives.Uint64Cls || right instanceof internal.primitives.Uint64Cls) { + return uint64BinaryOp(left, right, op) + } + if (left instanceof internal.primitives.BytesCls || right instanceof internal.primitives.BytesCls) { + return bytesBinaryOp(left, right, op) + } + const lbi = tryGetBigInt(left) + const rbi = tryGetBigInt(right) + if (lbi !== undefined && rbi !== undefined) { + const result = defaultBinaryOp(lbi, rbi, op) + + if (typeof result === 'boolean') { + return result + } + + if (typeof left === 'number' && typeof right === 'number' && result <= Number.MAX_SAFE_INTEGER) { + return Number(result) + } + + return result + } + return defaultBinaryOp(left, right, op) +} + +export function unaryOp(operand: unknown, op: UnaryOps) { + if (operand instanceof internal.primitives.Uint64Cls) { + return uint64UnaryOp(operand, op) + } + return defaultUnaryOp(operand, op) +} + +function uint64BinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps): DeliberateAny { + const lbi = internal.primitives.Uint64Cls.fromCompat(left).value + const rbi = internal.primitives.Uint64Cls.fromCompat(right).value + const result = (function () { + switch (op) { + case '+': + return lbi + rbi + case '-': + return lbi - rbi + case '*': + return lbi * rbi + case '**': + if (lbi === 0n && rbi === 0n) { + throw internal.errors.codeError('0 ** 0 is undefined') + } + return lbi ** rbi + case '/': + return lbi / rbi + case '%': + return lbi % rbi + case '>>': + if (rbi > 63n) { + throw new internal.errors.CodeError('expected shift <= 63') + } + return (lbi >> rbi) & MAX_UINT64 + case '<<': + if (rbi > 63n) { + throw new internal.errors.CodeError('expected shift <= 63') + } + return (lbi << rbi) & MAX_UINT64 + case '>': + return lbi > rbi + case '<': + return lbi < rbi + case '>=': + return lbi >= rbi + case '<=': + return lbi <= rbi + case '===': + return lbi === rbi + case '!==': + return lbi !== rbi + case '&': + return lbi & rbi + case '|': + return lbi | rbi + case '^': + return lbi ^ rbi + default: + internal.errors.internalError(`Unsupported operator ${op}`) + } + })() + return typeof result === 'boolean' ? result : new internal.primitives.Uint64Cls(result) +} + +function bigUintBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps): DeliberateAny { + const lbi = internal.primitives.checkBigUint(internal.primitives.BigUintCls.fromCompat(left).value) + const rbi = internal.primitives.checkBigUint(internal.primitives.BigUintCls.fromCompat(right).value) + const result = (function () { + switch (op) { + case '+': + return lbi + rbi + case '-': + return lbi - rbi + case '*': + return lbi * rbi + case '**': + if (lbi === 0n && rbi === 0n) { + throw internal.errors.codeError('0 ** 0 is undefined') + } + return lbi ** rbi + case '/': + return lbi / rbi + case '%': + return lbi % rbi + case '>>': + throw new internal.errors.CodeError('BigUint does not support >> operator') + case '<<': + throw new internal.errors.CodeError('BigUint does not support << operator') + case '>': + return lbi > rbi + case '<': + return lbi < rbi + case '>=': + return lbi >= rbi + case '<=': + return lbi <= rbi + case '===': + return lbi === rbi + case '!==': + return lbi !== rbi + case '&': + return lbi & rbi + case '|': + return lbi | rbi + case '^': + return lbi ^ rbi + default: + internal.errors.internalError(`Unsupported operator ${op}`) + } + })() + if (typeof result === 'boolean') { + return result + } + + if (result < 0) { + internal.errors.avmError('BigUint underflow') + } + return new internal.primitives.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 result = (function () { + switch (op) { + case '>': + return lbi > rbi + case '<': + return lbi < rbi + case '>=': + return lbi >= rbi + case '<=': + return lbi <= rbi + case '===': + return lbi === rbi + case '!==': + return lbi !== rbi + default: + internal.errors.internalError(`Unsupported operator ${op}`) + } + })() + return result +} + +function defaultBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps): DeliberateAny { + switch (op) { + case '+': + return left + right + case '-': + return left - right + case '*': + return left * right + case '**': + if (left === 0n && right === 0n) { + throw new internal.errors.CodeError('0 ** 0 is undefined') + } + return left ** right + case '/': + return left / right + case '%': + return left % right + case '>>': + if (typeof left === 'bigint' && typeof right === 'bigint') { + if (right > 63n) { + throw new internal.errors.CodeError('expected shift <= 63') + } + return (left >> right) & MAX_UINT64 + } + return left >> right + case '<<': + if (typeof left === 'bigint' && typeof right === 'bigint') { + if (right > 63n) { + throw new internal.errors.CodeError('expected shift <= 63') + } + return (left << right) & MAX_UINT64 + } + return left << right + case '>': + return left > right + case '<': + return left < right + case '>=': + return left >= right + case '<=': + return left <= right + case '===': + return left === right + case '!==': + return left !== right + case '&': + return left & right + case '|': + return left | right + case '^': + return left ^ right + default: + internal.errors.internalError(`Unsupported operator ${op}`) + } +} + +function uint64UnaryOp(operand: DeliberateAny, op: UnaryOps): DeliberateAny { + const obi = internal.primitives.Uint64Cls.fromCompat(operand).value + switch (op) { + case '~': + return ~obi & MAX_UINT64 + default: + internal.errors.internalError(`Unsupported operator ${op}`) + } +} + +function defaultUnaryOp(_operand: DeliberateAny, op: UnaryOps): DeliberateAny { + internal.errors.internalError(`Unsupported operator ${op}`) +} + +const genericTypeMap = new Map() +export function captureGenericTypeInfo(target: DeliberateAny, t: string) { + genericTypeMap.set(target, t) + return target +} + +export function getGenericTypeInfo(target: DeliberateAny): string | undefined { + return genericTypeMap.get(target) +} diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts new file mode 100644 index 0000000..a50145b --- /dev/null +++ b/src/subcontexts/contract-context.ts @@ -0,0 +1,144 @@ +import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, internal } from '@algorandfoundation/algo-ts' +import { getAbiMetadata, hasAbiMetadata } from '../abi-metadata' +import { lazyContext } from '../context-helpers/internal-context' +import { AccountCls } from '../impl/account' +import { ApplicationCls } from '../impl/application' +import { AssetCls } from '../impl/asset' +import { + ApplicationTransaction, + AssetConfigTransaction, + AssetFreezeTransaction, + AssetTransferTransaction, + KeyRegistrationTransaction, + PaymentTransaction, + Transaction, +} from '../impl/transactions' +import { getGenericTypeInfo } from '../runtime-helpers' +import { DeliberateAny } from '../typescript-helpers' +import { extractGenericTypeArgs } from '../util' + +interface IConstructor { + new (...args: DeliberateAny[]): T +} + +type StateTotals = Pick + +interface States { + globalStates: Map> + localStates: Map> + totals: StateTotals +} + +const isUint64GenericType = (typeName: string | undefined) => { + if (typeName === undefined) return false + const genericTypes: string[] = extractGenericTypeArgs(typeName) + return genericTypes.some((t) => t.toLocaleLowerCase() === 'uint64') +} + +const extractStates = (contract: BaseContract): States => { + const stateTotals = { globalNumBytes: 0, globalNumUint: 0, localNumBytes: 0, localNumUint: 0 } + const states = { + globalStates: new Map>(), + localStates: new Map>(), + totals: stateTotals, + } + Object.entries(contract).forEach(([key, value]) => { + const isLocalState = value instanceof Function && value.name === 'localStateInternal' + const isGlobalState = value instanceof internal.state.GlobalStateCls + if (isLocalState || isGlobalState) { + // set key using property name if not already set + if (value.key === undefined) value.key = Bytes(key) + + // capture state into the context + if (isLocalState) states.localStates.set(value.key, value.map) + else states.globalStates.set(value.key, value) + + // populate state totals + const isUint64State = isUint64GenericType(getGenericTypeInfo(value)!) + stateTotals.globalNumUint += isGlobalState && isUint64State ? 1 : 0 + stateTotals.globalNumBytes += isGlobalState && !isUint64State ? 1 : 0 + stateTotals.localNumUint += isLocalState && isUint64State ? 1 : 0 + stateTotals.localNumBytes += isLocalState && !isUint64State ? 1 : 0 + } + }) + return states +} + +const extractArraysFromArgs = (args: DeliberateAny[]) => { + const transactions: Transaction[] = [] + const accounts: Account[] = [] + const apps: Application[] = [] + const assets: Asset[] = [] + for (const arg of args) { + if (isTransaction(arg)) { + transactions.push(arg) + } else if (arg instanceof AccountCls) { + accounts.push(arg as Account) + } else if (arg instanceof ApplicationCls) { + apps.push(arg as Application) + } else if (arg instanceof AssetCls) { + assets.push(arg as Asset) + } + } + return { accounts, apps, assets, transactions } +} + +function isTransaction(obj: unknown): obj is Transaction { + return ( + obj instanceof PaymentTransaction || + obj instanceof KeyRegistrationTransaction || + obj instanceof AssetConfigTransaction || + obj instanceof AssetTransferTransaction || + obj instanceof AssetFreezeTransaction || + obj instanceof ApplicationTransaction + ) +} + +export class ContractContext { + create(type: IConstructor, ...args: DeliberateAny[]): T { + const proxy = new Proxy(type, this.getContractProxyHandler()) + return new proxy(...args) + } + + private getContractProxyHandler(): ProxyHandler> { + const onConstructed = (instance: BaseContract) => { + const states = extractStates(instance) + + const application = lazyContext.any.application({ + ...states.totals, + }) + lazyContext.ledger.addAppIdContractMap(application.id, instance) + } + return { + construct(target, args) { + let isArc4 = false + const instance = new Proxy(new target(...args), { + get(target, prop, receiver) { + const orig = Reflect.get(target, prop, receiver) + if (isArc4 || prop === 'approvalProgram' || prop === 'clearStateProgram') { + return (...args: DeliberateAny[]): DeliberateAny => { + const app = lazyContext.ledger.getApplicationForContract(receiver) + const { transactions, ...appCallArgs } = extractArraysFromArgs(args) + const abiMetadata = getAbiMetadata(receiver, prop as string) + const txns = [ + ...(transactions ?? []), + lazyContext.any.txn.applicationCall({ + appId: app, + ...appCallArgs, + onCompletion: (abiMetadata?.allowActions ?? [])[0], + }), + ] + return lazyContext.txn.ensureScope(txns).execute(() => (orig as DeliberateAny).apply(target, args)) + } + } + return orig + }, + }) + onConstructed(instance) + isArc4 = hasAbiMetadata(instance as Contract) + + return instance + }, + } + } +} diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts new file mode 100644 index 0000000..b18aa8c --- /dev/null +++ b/src/subcontexts/ledger-context.ts @@ -0,0 +1,79 @@ +import { Account, Application, Asset, BaseContract, internal } from '@algorandfoundation/algo-ts' +import { MAX_UINT64 } from '../constants' +import { AccountData, AssetHolding } from '../impl/account' +import { ApplicationData } from '../impl/application' +import { AssetData } from '../impl/asset' +import { asBigInt, asBytesCls, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' +import { GlobalData } from '../impl/global' + +export class LedgerContext { + appIdIter = iterBigInt(1001n, MAX_UINT64) + assetIdIter = iterBigInt(1001n, MAX_UINT64) + applicationDataMap = new Map() + appIdContractMap = new Map() + accountDataMap = new Map() + assetDataMap = new Map() + globalData = new GlobalData() + + addAppIdContractMap(appId: internal.primitives.StubUint64Compat, contract: BaseContract): void { + this.appIdContractMap.set(asBigInt(appId), contract) + } + + getAsset(assetId: internal.primitives.StubUint64Compat): Asset { + const id = asBigInt(assetId) + if (this.assetDataMap.has(id)) { + return Asset(asUint64(id)) + } + throw internal.errors.internalError('Unknown asset, check correct testing context is active') + } + + getApplication(applicationId: internal.primitives.StubUint64Compat): Application { + const id = asBigInt(applicationId) + if (this.applicationDataMap.has(id)) { + return Application(asUint64(id)) + } + throw internal.errors.internalError('Unknown application, check correct testing context is active') + } + + getApplicationForContract(contract: BaseContract): Application { + for (const [appId, c] of this.appIdContractMap) { + if (c === contract) { + if (this.applicationDataMap.has(appId)) { + return Application(asUint64(appId)) + } + } + } + throw internal.errors.internalError('Unknown contract, check correct testing context is active') + } + + /** + * Update asset holdings for account, only specified values will be updated. + * Account will also be opted-in to asset + * @param accountAddress + * @param assetId + * @param balance + * @param frozen + */ + updateAssetHolding( + accountAddress: internal.primitives.StubBytesCompat | Account, + assetId: internal.primitives.StubUint64Compat | Asset, + balance?: internal.primitives.StubUint64Compat, + frozen?: boolean, + ): void { + const addr = (asMaybeBytesCls(accountAddress) ?? asBytesCls((accountAddress as Account).bytes)).toString() + const id = (asMaybeUint64Cls(assetId) ?? asUint64Cls((assetId as Asset).id)).asBigInt() + const accountData = this.accountDataMap.get(addr)! + const asset = this.assetDataMap.get(id)! + const holding = accountData.optedAssets.get(id) ?? new AssetHolding(0n, asset.defaultFrozen) + if (balance !== undefined) holding.balance = asUint64(balance) + if (frozen !== undefined) holding.frozen = frozen + accountData.optedAssets.set(id, holding) + } + + patchGlobalData(data: Partial) { + this.globalData = { + ...this.globalData, + ...data, + } + } +} diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts new file mode 100644 index 0000000..01f40cc --- /dev/null +++ b/src/subcontexts/transaction-context.ts @@ -0,0 +1,142 @@ +import { internal, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import algosdk from 'algosdk' +import { lazyContext } from '../context-helpers/internal-context' +import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' +import { testInvariant } from '../errors' +import { AllTransactionFields, Transaction } from '../impl/transactions' +import { asBigInt, asUint64 } from '../util' + +function ScopeGenerator(dispose: () => void) { + function* internal() { + try { + yield + } finally { + dispose() + } + } + const scope = internal() + scope.next() + return { + done: () => { + scope.return() + }, + } +} + +interface ExecutionScope { + execute: (body: () => TReturn) => TReturn +} + +export class TransactionContext { + readonly groups: TransactionGroup[] = [] + #activeGroup: TransactionGroup | undefined + + createScope(group: Transaction[], activeTransactionIndex?: number): ExecutionScope { + const transactionGroup = new TransactionGroup(group, activeTransactionIndex) + const previousGroup = this.#activeGroup + this.#activeGroup = transactionGroup + + const scope = ScopeGenerator(() => { + if (this.#activeGroup?.transactions?.length) { + this.groups.push(this.#activeGroup) + } + this.#activeGroup = previousGroup + }) + return { + execute: (body: () => TReturn) => { + const result = body() + scope.done() + return result + }, + } + } + + ensureScope(group: Transaction[], activeTransactionIndex?: number): ExecutionScope { + if (!this.#activeGroup || !this.#activeGroup.transactions.length) { + return this.createScope(group, activeTransactionIndex) + } + return { + execute: (body: () => TReturn) => { + return body() + }, + } + } + + get activeGroup(): TransactionGroup { + if (this.#activeGroup) { + return this.#activeGroup + } + throw internal.errors.internalError('no active txn group') + } + + get lastGroup(): TransactionGroup { + if (this.groups.length === 0) { + internal.errors.internalError('No group transactions found!') + } + return this.groups.at(-1)! + } + + get lastActive(): Transaction { + return this.lastGroup.activeTransaction + } + + /* internal */ + appendLog(value: internal.primitives.StubBytesCompat): void { + const activeTransaction = this.activeGroup.activeTransaction + if (activeTransaction.type !== TransactionType.ApplicationCall) { + throw internal.errors.internalError('Can only add logs to ApplicationCallTransaction!') + } + activeTransaction.appendLog(value) + } + + exportLogs(appId: uint64, ...decoding: T): DecodedLogs { + const transaction = this.groups + .flatMap((g) => g.transactions) + .filter((t) => t.type === TransactionType.ApplicationCall) + .find((t) => asBigInt(t.appId.id) === asBigInt(appId)) + let logs = [] + if (transaction) { + logs = transaction.appLogs + } else { + logs = lazyContext.getApplicationData(appId).appLogs + } + const rawLogs = logs.map((l) => internal.primitives.toExternalValue(l)) + return decodeLogs(rawLogs, decoding) + } +} + +export class TransactionGroup { + activeTransactionIndex: number + latestTimestamp: number + transactions: Transaction[] + + constructor(transactions: Transaction[], activeTransactionIndex?: number) { + this.latestTimestamp = Date.now() + if (transactions.length > algosdk.AtomicTransactionComposer.MAX_GROUP_SIZE) { + internal.errors.internalError( + `Transaction group can have at most ${algosdk.AtomicTransactionComposer.MAX_GROUP_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 + } + + get activeTransaction() { + return this.transactions[this.activeTransactionIndex] + } + + get activeApplicationId() { + if (this.transactions.length === 0) { + internal.errors.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 + } + + 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) + } +} diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts new file mode 100644 index 0000000..950dcad --- /dev/null +++ b/src/test-execution-context.ts @@ -0,0 +1,89 @@ +import { Account, Application, Asset, Bytes, bytes, internal, uint64 } from '@algorandfoundation/algo-ts' +import algosdk from 'algosdk' +import { captureMethodConfig } from './abi-metadata' +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 { ContractContext } from './subcontexts/contract-context' +import { LedgerContext } from './subcontexts/ledger-context' +import { TransactionContext } from './subcontexts/transaction-context' +import { ValueGenerator } from './value-generators' + +export class TestExecutionContext implements internal.ExecutionContext { + #applicationLogs: Map + #contractContext: ContractContext + #ledgerContext: LedgerContext + #txnContext: TransactionContext + #valueGenerator: ValueGenerator + #defaultSender: Account + + constructor() { + internal.ctxMgr.instance = this + this.#applicationLogs = new Map() + this.#contractContext = new ContractContext() + this.#ledgerContext = new LedgerContext() + this.#txnContext = new TransactionContext() + this.#valueGenerator = new ValueGenerator() + this.#defaultSender = Account(Bytes(algosdk.generateAccount().addr)) + } + + account(address?: bytes): Account { + return new AccountCls(address) + } + + application(id?: uint64): Application { + return new ApplicationCls(id) + } + + asset(id?: uint64): Asset { + return new AssetCls(id) + } + + log(value: bytes): void { + this.txn.appendLog(value) + } + + exportLogs(appId: uint64, ...decoding: T): DecodedLogs { + return this.txn.exportLogs(appId, ...decoding) + } + + get op() { + return ops + } + get contract() { + return this.#contractContext + } + + get ledger() { + return this.#ledgerContext + } + + get txn() { + return this.#txnContext + } + + get any() { + return this.#valueGenerator + } + + get defaultSender(): Account { + return this.#defaultSender + } + + get abiMetadata() { + return { + captureMethodConfig, + } + } + + reset() { + this.#applicationLogs.clear() + this.#contractContext = new ContractContext() + this.#ledgerContext = new LedgerContext() + this.#txnContext = new TransactionContext() + internal.ctxMgr.reset() + internal.ctxMgr.instance = this + } +} diff --git a/src/test-transformer/errors.ts b/src/test-transformer/errors.ts new file mode 100644 index 0000000..5f2f7d7 --- /dev/null +++ b/src/test-transformer/errors.ts @@ -0,0 +1,5 @@ +export class TransformerError extends Error { + constructor(message: string) { + super(message) + } +} diff --git a/src/test-transformer/helpers.ts b/src/test-transformer/helpers.ts new file mode 100644 index 0000000..d64bf69 --- /dev/null +++ b/src/test-transformer/helpers.ts @@ -0,0 +1,12 @@ +import ts from 'typescript' +import { TransformerError } from './errors' + +export const getPropertyNameAsString = (name: ts.PropertyName): ts.Identifier | ts.StringLiteral | ts.NoSubstitutionTemplateLiteral => { + if (ts.isStringLiteralLike(name)) { + return name + } + if (ts.isIdentifier(name)) { + return ts.factory.createStringLiteral(name.text) + } + throw new TransformerError(`Node ${name.kind} cannot be converted to a static string`) +} diff --git a/src/test-transformer/index.ts b/src/test-transformer/index.ts new file mode 100644 index 0000000..bb11ff2 --- /dev/null +++ b/src/test-transformer/index.ts @@ -0,0 +1,22 @@ +import type ts from 'typescript' +import { registerPTypes, typeRegistry } from '@algorandfoundation/puya-ts/internal' +import type { DeliberateAny } from '../typescript-helpers' +import { SourceFileVisitor } from './visitors' + +const includes: string[] = ['.algo.ts', '.spec.ts'] +const programTransformer = { + type: 'program', + factory(program: ts.Program): ts.TransformerFactory { + registerPTypes(typeRegistry) + return (context) => { + return (sourceFile) => { + if (!includes.some((i) => sourceFile.fileName.endsWith(i))) return sourceFile + return new SourceFileVisitor(context, sourceFile, program).result() + } + } + }, +} + +// 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 = programTransformer as DeliberateAny diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts new file mode 100644 index 0000000..564bdc4 --- /dev/null +++ b/src/test-transformer/node-factory.ts @@ -0,0 +1,71 @@ +import ts from 'typescript' + +import { FunctionPType } from '@algorandfoundation/puya-ts/internal' +import type { DeliberateAny } from '../typescript-helpers' +import { getPropertyNameAsString } from './helpers' + +const factory = ts.factory +export const nodeFactory = { + importHelpers() { + return factory.createImportDeclaration( + undefined, + factory.createImportClause(false, undefined, factory.createNamespaceImport(factory.createIdentifier('runtimeHelpers'))), + factory.createStringLiteral('@algorandfoundation/algo-ts-testing/runtime-helpers'), + undefined, + ) + }, + + switchableValue(x: ts.Expression) { + return factory.createCallExpression( + factory.createPropertyAccessExpression(factory.createIdentifier('runtimeHelpers'), factory.createIdentifier('switchableValue')), + undefined, + [x], + ) + }, + binaryOp(left: ts.Expression, right: ts.Expression, op: string) { + return factory.createCallExpression( + factory.createPropertyAccessExpression(factory.createIdentifier('runtimeHelpers'), factory.createIdentifier('binaryOp')), + undefined, + [left, right, factory.createStringLiteral(op)], + ) + }, + + prefixUnaryOp(operand: ts.Expression, op: string) { + return factory.createCallExpression( + factory.createPropertyAccessExpression(factory.createIdentifier('runtimeHelpers'), factory.createIdentifier('unaryOp')), + undefined, + [operand, factory.createStringLiteral(op)], + ) + }, + + attachMetaData(classIdentifier: ts.Identifier, method: ts.MethodDeclaration, functionType: FunctionPType) { + const methodName = getPropertyNameAsString(method.name) + const metadata = factory.createObjectLiteralExpression([ + factory.createPropertyAssignment('methodName', methodName), + factory.createPropertyAssignment('methodSelector', methodName), + factory.createPropertyAssignment( + 'argTypes', + factory.createArrayLiteralExpression(functionType.parameters.map((p) => factory.createStringLiteral(p[1].fullName))), + ), + factory.createPropertyAssignment('returnType', factory.createStringLiteral(functionType.returnType.fullName)), + ]) + return factory.createExpressionStatement( + factory.createCallExpression( + factory.createPropertyAccessExpression(factory.createIdentifier('runtimeHelpers'), factory.createIdentifier('attachAbiMetadata')), + undefined, + [classIdentifier, methodName, metadata], + ), + ) + }, + + captureGenericTypeInfo(x: ts.Expression, type: string) { + return factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier('runtimeHelpers'), + factory.createIdentifier('captureGenericTypeInfo'), + ), + undefined, + [x, factory.createStringLiteral(type)], + ) + }, +} satisfies Record ts.Node> diff --git a/src/test-transformer/supported-binary-op-string.ts b/src/test-transformer/supported-binary-op-string.ts new file mode 100644 index 0000000..74e67a0 --- /dev/null +++ b/src/test-transformer/supported-binary-op-string.ts @@ -0,0 +1,76 @@ +import type { BinaryOperator, PrefixUnaryOperator } from 'typescript' +import ts from 'typescript' + +export function supportedBinaryOpString(x: BinaryOperator): string | undefined { + switch (x) { + case ts.SyntaxKind.MinusToken: + return '-' + case ts.SyntaxKind.PlusToken: + return '+' + case ts.SyntaxKind.EqualsEqualsEqualsToken: + return '===' + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + return '!==' + case ts.SyntaxKind.GreaterThanToken: + return '>' + case ts.SyntaxKind.GreaterThanEqualsToken: + return '>=' + case ts.SyntaxKind.GreaterThanGreaterThanToken: + return '>>' + case ts.SyntaxKind.LessThanToken: + return '<' + case ts.SyntaxKind.LessThanEqualsToken: + return '<=' + case ts.SyntaxKind.LessThanLessThanToken: + return '<<' + case ts.SyntaxKind.AsteriskToken: + return '*' + case ts.SyntaxKind.AsteriskAsteriskToken: + return '**' + case ts.SyntaxKind.SlashToken: + return '/' + case ts.SyntaxKind.PercentToken: + return '%' + case ts.SyntaxKind.AmpersandToken: + return '&' + case ts.SyntaxKind.BarToken: + return '|' + case ts.SyntaxKind.CaretToken: + return '^' + case ts.SyntaxKind.AmpersandAmpersandEqualsToken: + case ts.SyntaxKind.AmpersandAmpersandToken: + case ts.SyntaxKind.AmpersandEqualsToken: + case ts.SyntaxKind.AsteriskAsteriskEqualsToken: + case ts.SyntaxKind.AsteriskEqualsToken: + case ts.SyntaxKind.BarBarEqualsToken: + case ts.SyntaxKind.BarBarToken: + case ts.SyntaxKind.BarEqualsToken: + case ts.SyntaxKind.CaretEqualsToken: + case ts.SyntaxKind.CommaToken: + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.EqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.InKeyword: + case ts.SyntaxKind.InstanceOfKeyword: + case ts.SyntaxKind.PercentEqualsToken: + case ts.SyntaxKind.PlusEqualsToken: + case ts.SyntaxKind.QuestionQuestionEqualsToken: + case ts.SyntaxKind.MinusEqualsToken: + case ts.SyntaxKind.SlashEqualsToken: + case ts.SyntaxKind.QuestionQuestionToken: + case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: + case ts.SyntaxKind.LessThanLessThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + return undefined + } +} + +export function supportedPrefixUnaryOpString(x: PrefixUnaryOperator): string | undefined { + switch (x) { + case ts.SyntaxKind.TildeToken: + return '~' + default: + return undefined + } +} diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts new file mode 100644 index 0000000..c31920b --- /dev/null +++ b/src/test-transformer/visitors.ts @@ -0,0 +1,164 @@ +import ts from 'typescript' +import { + ContractClassPType, + FunctionPType, + PType, + SourceLocation, + TypeResolver, + anyPType, + typeRegistry, +} from '@algorandfoundation/puya-ts/internal' +import { nodeFactory } from './node-factory' +import { supportedBinaryOpString, supportedPrefixUnaryOpString } from './supported-binary-op-string' + +const { factory } = ts + +type VisitorHelper = { + additionalStatements: ts.Statement[] + resolveType(node: ts.Node): PType + sourceLocation(node: ts.Node): SourceLocation +} + +export class SourceFileVisitor { + private helper: VisitorHelper + constructor( + private context: ts.TransformationContext, + private sourceFile: ts.SourceFile, + program: ts.Program, + ) { + const typeResolver = new TypeResolver(program.getTypeChecker(), program.getCurrentDirectory()) + + this.helper = { + additionalStatements: [], + resolveType(node: ts.Node): PType { + try { + return typeResolver.resolve(node, this.sourceLocation(node)) + } catch { + return anyPType + } + }, + sourceLocation(node: ts.Node): SourceLocation { + return SourceLocation.fromNode(sourceFile, node, program.getCurrentDirectory()) + }, + } + } + + public result(): ts.SourceFile { + const updatedSourceFile = ts.visitNode(this.sourceFile, this.visit) as ts.SourceFile + + return factory.updateSourceFile(updatedSourceFile, [ + nodeFactory.importHelpers(), + ...updatedSourceFile.statements, + ...this.helper.additionalStatements, + ]) + } + + private visit = (node: ts.Node): ts.Node => { + if (ts.isFunctionLike(node)) { + return new FunctionLikeDecVisitor(this.context, node).result() + } + if (ts.isClassDeclaration(node)) { + return new ClassVisitor(this.context, this.helper, node).result() + } + + return ts.visitEachChild(node, this.visit, this.context) + } +} + +class FunctionOrMethodVisitor { + constructor(protected context: ts.TransformationContext) {} + protected visit = (node: ts.Node): ts.Node => { + return ts.visitEachChild(this.updateNode(node), this.visit, this.context) + } + + protected updateNode(node: ts.Node): ts.Node { + if (ts.isSwitchStatement(node)) { + return factory.updateSwitchStatement(node, nodeFactory.switchableValue(node.expression), node.caseBlock) + } + + if (ts.isCaseClause(node)) { + return factory.updateCaseClause(node, nodeFactory.switchableValue(node.expression), node.statements) + } + + if (ts.isBinaryExpression(node)) { + const tokenText = supportedBinaryOpString(node.operatorToken.kind) + if (tokenText) { + return nodeFactory.binaryOp(node.left, node.right, tokenText) + } + } + if (ts.isPrefixUnaryExpression(node)) { + const tokenText = supportedPrefixUnaryOpString(node.operator) + if (tokenText) { + return nodeFactory.prefixUnaryOp(node.operand, tokenText) + } + } + return node + } +} + +class FunctionLikeDecVisitor extends FunctionOrMethodVisitor { + constructor( + context: ts.TransformationContext, + private funcNode: ts.SignatureDeclaration, + ) { + super(context) + } + + public result(): ts.SignatureDeclaration { + return ts.visitNode(this.funcNode, this.visit) as ts.SignatureDeclaration + } +} +class MethodDecVisitor extends FunctionOrMethodVisitor { + constructor( + context: ts.TransformationContext, + private methodNode: ts.MethodDeclaration, + ) { + super(context) + } + + public result(): ts.MethodDeclaration { + return ts.visitNode(this.methodNode, this.visit) as ts.MethodDeclaration + } +} + +class ClassVisitor { + private isArc4: boolean + constructor( + private context: ts.TransformationContext, + private helper: VisitorHelper, + private classDec: ts.ClassDeclaration, + ) { + const classType = helper.resolveType(classDec) + this.isArc4 = classType instanceof ContractClassPType && classType.isARC4 + } + + public result(): ts.ClassDeclaration { + return this.visit(this.classDec) as ts.ClassDeclaration + } + + private visit = (node: ts.Node): ts.Node => { + if (ts.isMethodDeclaration(node)) { + if (this.classDec.name && this.isArc4) { + const methodType = this.helper.resolveType(node) + if (methodType instanceof FunctionPType) { + this.helper.additionalStatements.push(nodeFactory.attachMetaData(this.classDec.name, node, methodType)) + } + } + + return new MethodDecVisitor(this.context, node).result() + } + + if (ts.isCallExpression(node)) { + let type = this.helper.resolveType(node) + + // `voted = LocalState()` is resolved to FunctionPType with returnType LocalState + if (type instanceof FunctionPType) type = type.returnType + + if (typeRegistry.isGeneric(type)) { + const typeName = type.name + return nodeFactory.captureGenericTypeInfo(ts.visitEachChild(node, this.visit, this.context), typeName) + } + } + return ts.visitEachChild(node, this.visit, this.context) + } +} diff --git a/src/typescript-helpers.ts b/src/typescript-helpers.ts new file mode 100644 index 0000000..9e03cc3 --- /dev/null +++ b/src/typescript-helpers.ts @@ -0,0 +1,20 @@ +// Sometimes only an 'any' will do. Don't use this just to be lazy though +/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ +export type DeliberateAny = any +export type AnyFunction = (...args: DeliberateAny[]) => DeliberateAny +export type Mutable = { + -readonly [P in keyof T]: T[P] +} + +export type KeyIsFunction = TKey extends DeliberateAny + ? TObj[TKey] extends AnyFunction + ? TKey + : never + : never +export type KeyIsNotFunction = TKey extends DeliberateAny + ? TObj[TKey] extends AnyFunction + ? never + : TKey + : never +export type ObjectKeys = KeyIsNotFunction +export type FunctionKeys = KeyIsFunction diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..a4036dd --- /dev/null +++ b/src/util.ts @@ -0,0 +1,121 @@ +import { internal } from '@algorandfoundation/algo-ts' +import { randomBytes } from 'crypto' +import { BITS_IN_BYTE, MAX_UINT512, MAX_UINT8, UINT512_SIZE } from './constants' +import { DeliberateAny } from './typescript-helpers' + +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 +} + +export function* iterBigInt(start: bigint, end: bigint): Generator { + for (let i = start; i < end; i++) { + yield BigInt(i) + } +} + +export const asBigInt = (v: internal.primitives.StubUint64Compat): bigint => asUint64Cls(v).asBigInt() + +export const asNumber = (v: internal.primitives.StubUint64Compat): number => asUint64Cls(v).asNumber() + +export function extractGenericTypeArgs(t: string): string[] { + const match = t.match(/<(.*)>/) + if (!match) return [] + return match[1].split(',').map((x) => x.trim()) +} + +export const asUint64Cls = (val: internal.primitives.StubUint64Compat) => internal.primitives.Uint64Cls.fromCompat(val) + +export const asBigUintCls = (val: internal.primitives.StubBigUintCompat) => internal.primitives.BigUintCls.fromCompat(val) + +export const asBytesCls = (val: internal.primitives.StubBytesCompat) => internal.primitives.BytesCls.fromCompat(val) + +export const asUint64 = (val: internal.primitives.StubUint64Compat) => asUint64Cls(val).asAlgoTs() + +export const asBigUint = (val: internal.primitives.StubBigUintCompat) => asBigUintCls(val).asAlgoTs() + +export const asBytes = (val: internal.primitives.StubBytesCompat) => asBytesCls(val).asAlgoTs() + +export const asMaybeUint64Cls = (val: DeliberateAny) => { + try { + return internal.primitives.Uint64Cls.fromCompat(val) + } catch (e) { + if (e instanceof internal.errors.InternalError) { + // swallow error and return undefined + } else { + throw e + } + } + return undefined +} + +export const asMaybeBytesCls = (val: DeliberateAny) => { + try { + return internal.primitives.BytesCls.fromCompat(val) + } catch (e) { + if (e instanceof internal.errors.InternalError) { + // swallow error and return undefined + } else { + throw e + } + } + 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 getRandomNumber = (min: number, max: number): number => { + return Math.floor(Math.random() * (max - min + 1)) + min +} + +export const getRandomBigInt = (min: number | bigint, max: number | bigint): bigint => { + const bigIntMin = BigInt(min) + const bigIntMax = BigInt(max) + const randomValue = [...Array(UINT512_SIZE / BITS_IN_BYTE).keys()] + .map(() => getRandomNumber(0, MAX_UINT8)) + .reduce((acc, x) => acc * 256n + BigInt(x), 0n) + return (randomValue % (bigIntMax - bigIntMin)) + bigIntMin +} + +export const getRandomBytes = (length: number): internal.primitives.BytesCls => asBytesCls(new Uint8Array(randomBytes(length))) + +const NoValue = Symbol('no-value') +type LazyInstance = () => T +export const Lazy = (factory: () => T): LazyInstance => { + let val: T | typeof NoValue = NoValue + + return () => { + if (val === NoValue) { + val = factory() + } + return val + } +} + +const ObjectReferenceSymbol = Symbol('ObjectReference') +const objectRefIter = iterBigInt(1001n, MAX_UINT512) +export const getObjectReference = (obj: DeliberateAny): bigint => { + const tryGetReference = (obj: DeliberateAny): bigint | undefined => { + const s = Object.getOwnPropertySymbols(obj).find((s) => s.toString() === ObjectReferenceSymbol.toString()) + return s ? obj[s] : ObjectReferenceSymbol in obj ? obj[ObjectReferenceSymbol] : undefined + } + const existingRef = tryGetReference(obj) + if (existingRef !== undefined) { + return existingRef + } + const ref = objectRefIter.next().value + Object.defineProperty(obj, ObjectReferenceSymbol, { + value: ref, + enumerable: false, + writable: false, + }) + + return ref +} diff --git a/src/value-generators/avm.ts b/src/value-generators/avm.ts new file mode 100644 index 0000000..586bfbc --- /dev/null +++ b/src/value-generators/avm.ts @@ -0,0 +1,112 @@ +import { Account, Application, Asset, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import algosdk from 'algosdk' +import { randomBytes } from 'crypto' +import { MAX_BYTES_SIZE, MAX_UINT64, ZERO_ADDRESS } from '../constants' +import { lazyContext } from '../context-helpers/internal-context' +import { AccountCls, AccountData } from '../impl/account' +import { ApplicationCls, ApplicationData } from '../impl/application' +import { AssetCls, AssetData } from '../impl/asset' +import { asBigInt, asBytesCls, asUint64Cls, getRandomBigInt } from '../util' + +type AccountContextData = Partial & { + address?: internal.primitives.StubBytesCompat + optedAssetBalances?: Map + optedApplications?: Application[] +} + +type AssetContextData = Partial & { assetId?: internal.primitives.StubUint64Compat } + +type ApplicationContextData = Partial & { applicationId?: internal.primitives.StubUint64Compat } + +export class AvmValueGenerator { + uint64(minValue: number | bigint = 0n, maxValue: number | bigint = MAX_UINT64): uint64 { + if (maxValue > MAX_UINT64) { + internal.errors.internalError('maxValue must be less than or equal to MAX_UINT64') + } + if (minValue > maxValue) { + internal.errors.internalError('minValue must be less than or equal to maxValue') + } + if (minValue < 0n || maxValue < 0n) { + internal.errors.internalError('minValue and maxValue must be greater than or equal to 0') + } + return Uint64(getRandomBigInt(minValue, maxValue)) + } + + bytes(length = MAX_BYTES_SIZE): bytes { + return Bytes(new Uint8Array(randomBytes(length))) + } + + account(input?: AccountContextData): Account { + const addr = input?.address ? asBytesCls(input.address).toString() : undefined + if (addr && lazyContext.ledger.accountDataMap.has(addr)) { + internal.errors.internalError( + 'Account with such address already exists in testing context. Use `context.ledger.getAccount(address)` to retrieve the existing account.', + ) + } + + const accountAddress = addr ?? algosdk.generateAccount().addr + const data = new AccountData() + const { address, optedAssetBalances, optedApplications, ...account } = input ?? {} + data.account = { + ...data.account, + ...account, + } + lazyContext.ledger.accountDataMap.set(accountAddress, data) + + if (input?.optedAssetBalances) { + for (const [assetId, balance] of input.optedAssetBalances) { + lazyContext.ledger.updateAssetHolding(accountAddress, assetId, balance) + } + } + if (input?.optedApplications) { + for (const app of input.optedApplications) { + data.optedApplications.set(asBigInt(app.id), app) + } + } + return new AccountCls(Bytes(accountAddress)) + } + + asset(input?: AssetContextData): Asset { + const id = input?.assetId + if (id && lazyContext.ledger.assetDataMap.has(asBigInt(id))) { + internal.errors.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 { assetId: _, ...assetData } = input ?? {} + lazyContext.ledger.assetDataMap.set(assetId.asBigInt(), { + ...defaultAssetData, + ...assetData, + }) + return new AssetCls(assetId.asAlgoTs()) + } + + application(input?: ApplicationContextData): Application { + const id = input?.applicationId + if (id && lazyContext.ledger.applicationDataMap.has(asBigInt(id))) { + internal.errors.internalError('Application with such ID already exists in testing context!') + } + const applicationId = asUint64Cls(id ?? lazyContext.ledger.appIdIter.next().value) + const data = new ApplicationData() + const { applicationId: _, ...applicationData } = input ?? {} + data.application = { + ...data.application, + ...applicationData, + } + lazyContext.ledger.applicationDataMap.set(applicationId.asBigInt(), data) + return new ApplicationCls(applicationId.asAlgoTs()) + } +} diff --git a/src/value-generators/index.ts b/src/value-generators/index.ts new file mode 100644 index 0000000..ad3fe82 --- /dev/null +++ b/src/value-generators/index.ts @@ -0,0 +1,11 @@ +import { AvmValueGenerator } from './avm' +import { TxnValueGenerator } from './txn' + +export class ValueGenerator extends AvmValueGenerator { + txn: TxnValueGenerator + + constructor() { + super() + this.txn = new TxnValueGenerator() + } +} diff --git a/src/value-generators/txn.ts b/src/value-generators/txn.ts new file mode 100644 index 0000000..82a3aab --- /dev/null +++ b/src/value-generators/txn.ts @@ -0,0 +1,47 @@ +import { gtxn, internal } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' +import { + ApplicationTransaction, + ApplicationTransactionFields, + AssetConfigTransaction, + AssetFreezeTransaction, + AssetTransferTransaction, + KeyRegistrationTransaction, + PaymentTransaction, + TxnFields, +} from '../impl/transactions' +import { asBigInt } from '../util' + +export class TxnValueGenerator { + applicationCall(fields?: ApplicationTransactionFields): ApplicationTransaction { + const params = fields ?? {} + if (params.appId && !lazyContext.ledger.applicationDataMap.has(asBigInt(params.appId.id))) { + internal.errors.internalError(`Application ID ${params.appId.id} not found in test context`) + } + if (!params.appId) { + params.appId = lazyContext.any.application() + } + + return ApplicationTransaction.create(params) + } + + payment(fields?: TxnFields): PaymentTransaction { + return PaymentTransaction.create(fields ?? {}) + } + + keyRegistration(fields?: TxnFields): KeyRegistrationTransaction { + return KeyRegistrationTransaction.create(fields ?? {}) + } + + assetConfig(fields?: TxnFields): AssetConfigTransaction { + return AssetConfigTransaction.create(fields ?? {}) + } + + assetTransfer(fields?: TxnFields): AssetTransferTransaction { + return AssetTransferTransaction.create(fields ?? {}) + } + + assetFreeze(fields?: TxnFields): AssetFreezeTransaction { + return AssetFreezeTransaction.create(fields ?? {}) + } +} diff --git a/tests/artifacts/created-app-asset/contract.algo.ts b/tests/artifacts/created-app-asset/contract.algo.ts new file mode 100644 index 0000000..0747372 --- /dev/null +++ b/tests/artifacts/created-app-asset/contract.algo.ts @@ -0,0 +1,28 @@ +import { arc4, assert, Bytes, gtxn, op, uint64 } from '@algorandfoundation/algo-ts' + +export class AppExpectingEffects extends arc4.Contract { + @arc4.abimethod() + public create_group(assetCreate: gtxn.AssetConfigTxn, appCreate: gtxn.ApplicationTxn): readonly [uint64, uint64] { + assert(assetCreate.createdAsset.id, 'expected asset created') + assert(op.gaid(assetCreate.groupIndex) === assetCreate.createdAsset.id, 'expected correct asset id') + assert(appCreate.createdApp.id, 'expected app created') + assert(op.gaid(appCreate.groupIndex) === appCreate.createdApp.id, 'expected correct app id') + + return [assetCreate.createdAsset.id, appCreate.createdApp.id] + } + + @arc4.abimethod() + public log_group(appCall: gtxn.ApplicationTxn): void { + assert(appCall.appArgs(0) === Bytes('some_value()uint64'), 'expected correct method called') + assert(appCall.numLogs === 1, 'expected logs') + assert(appCall.lastLog === Bytes('this is a log statement')) + } + + // TODO: uncomment when arc4 stubs are implemented + // @arc4.abimethod() + // public log_group(appCall: gtxn.ApplicationTxn): void { + // assert(appCall.appArgs(0) === arc4.arc4Signature("some_value()uint64"), "expected correct method called") + // assert(appCall.numLogs === 1, "expected logs") + // assert(arc4.UInt64.from_log(appCall.lastLog) === (appCall.groupIndex + 1) * Global.groupSize) + // } +} diff --git a/tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal b/tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal new file mode 100644 index 0000000..748efa2 --- /dev/null +++ b/tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal @@ -0,0 +1,871 @@ +#pragma version 10 + +tests.artifacts.CryptoOps.contract.CryptoOpsContract.approval_program: + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@17 + 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 main_verify_sha256_route@2 main_verify_sha3_256_route@3 main_verify_keccak_256_route@4 main_verify_sha512_256_route@5 main_verify_ed25519verify_route@6 main_verify_ed25519verify_bare_route@7 main_verify_ecdsa_verify_k1_route@8 main_verify_ecdsa_verify_r1_route@9 main_verify_ecdsa_recover_k1_route@10 main_verify_ecdsa_recover_r1_route@11 main_verify_ecdsa_decompress_k1_route@12 main_verify_ecdsa_decompress_r1_route@13 main_verify_vrf_verify_route@14 + err // reject transaction + +main_verify_sha256_route@2: + // tests/artifacts/CryptoOps/contract.py:5 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/CryptoOps/contract.py:5 + // @arc4.abimethod() + callsub verify_sha256 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_sha3_256_route@3: + // tests/artifacts/CryptoOps/contract.py:11 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/CryptoOps/contract.py:11 + // @arc4.abimethod() + callsub verify_sha3_256 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_keccak_256_route@4: + // tests/artifacts/CryptoOps/contract.py:17 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/CryptoOps/contract.py:17 + // @arc4.abimethod() + callsub verify_keccak_256 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_sha512_256_route@5: + // tests/artifacts/CryptoOps/contract.py:23 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/CryptoOps/contract.py:23 + // @arc4.abimethod() + callsub verify_sha512_256 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ed25519verify_route@6: + // tests/artifacts/CryptoOps/contract.py:29 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + extract 2 0 + // tests/artifacts/CryptoOps/contract.py:29 + // @arc4.abimethod() + callsub verify_ed25519verify + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ed25519verify_bare_route@7: + // tests/artifacts/CryptoOps/contract.py:35 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + extract 2 0 + // tests/artifacts/CryptoOps/contract.py:35 + // @arc4.abimethod() + callsub verify_ed25519verify_bare + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_verify_k1_route@8: + // tests/artifacts/CryptoOps/contract.py:41 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + 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/CryptoOps/contract.py:41 + // @arc4.abimethod() + callsub verify_ecdsa_verify_k1 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_verify_r1_route@9: + // tests/artifacts/CryptoOps/contract.py:47 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + 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/CryptoOps/contract.py:47 + // @arc4.abimethod() + callsub verify_ecdsa_verify_r1 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_recover_k1_route@10: + // tests/artifacts/CryptoOps/contract.py:53 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + extract 2 0 + txna ApplicationArgs 4 + extract 2 0 + // tests/artifacts/CryptoOps/contract.py:53 + // @arc4.abimethod() + callsub verify_ecdsa_recover_k1 + swap + dup + len + itob + extract 6 2 + swap + concat + dig 1 + len + itob + extract 6 2 + uncover 2 + concat + swap + dup + len + int 4 + + + itob + extract 6 2 + byte 0x0004 + swap + concat + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_recover_r1_route@11: + // tests/artifacts/CryptoOps/contract.py:60 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + extract 2 0 + txna ApplicationArgs 4 + extract 2 0 + // tests/artifacts/CryptoOps/contract.py:60 + // @arc4.abimethod() + callsub verify_ecdsa_recover_r1 + swap + dup + len + itob + extract 6 2 + swap + concat + dig 1 + len + itob + extract 6 2 + uncover 2 + concat + swap + dup + len + int 4 + + + itob + extract 6 2 + byte 0x0004 + swap + concat + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_decompress_k1_route@12: + // tests/artifacts/CryptoOps/contract.py:70 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/CryptoOps/contract.py:70 + // @arc4.abimethod() + callsub verify_ecdsa_decompress_k1 + swap + dup + len + itob + extract 6 2 + swap + concat + dig 1 + len + itob + extract 6 2 + uncover 2 + concat + swap + dup + len + int 4 + + + itob + extract 6 2 + byte 0x0004 + swap + concat + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_ecdsa_decompress_r1_route@13: + // tests/artifacts/CryptoOps/contract.py:75 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/CryptoOps/contract.py:75 + // @arc4.abimethod() + callsub verify_ecdsa_decompress_r1 + swap + dup + len + itob + extract 6 2 + swap + concat + dig 1 + len + itob + extract 6 2 + uncover 2 + concat + swap + dup + len + int 4 + + + itob + extract 6 2 + byte 0x0004 + swap + concat + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_vrf_verify_route@14: + // tests/artifacts/CryptoOps/contract.py:80 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + extract 2 0 + // tests/artifacts/CryptoOps/contract.py:80 + // @arc4.abimethod() + callsub verify_vrf_verify + swap + dup + len + itob + extract 6 2 + swap + concat + byte 0x00 + int 0 + uncover 3 + setbit + byte 0x0003 + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@17: + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_sha256(a: bytes, pad_size: uint64) -> bytes: +verify_sha256: + // tests/artifacts/CryptoOps/contract.py:5-6 + // @arc4.abimethod() + // def verify_sha256(self, a: Bytes, pad_size: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/CryptoOps/contract.py:7 + // a = op.bzero(pad_size) + a + frame_dig -1 + bzero + frame_dig -2 + concat + dup + frame_bury -2 + // tests/artifacts/CryptoOps/contract.py:8 + // result = op.sha256(a) + sha256 + // tests/artifacts/CryptoOps/contract.py:9 + // return result + retsub + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_sha3_256(a: bytes, pad_size: uint64) -> bytes: +verify_sha3_256: + // tests/artifacts/CryptoOps/contract.py:11-12 + // @arc4.abimethod() + // def verify_sha3_256(self, a: Bytes, pad_size: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/CryptoOps/contract.py:13 + // a = op.bzero(pad_size) + a + frame_dig -1 + bzero + frame_dig -2 + concat + dup + frame_bury -2 + // tests/artifacts/CryptoOps/contract.py:14 + // result = op.sha3_256(a) + sha3_256 + // tests/artifacts/CryptoOps/contract.py:15 + // return result + retsub + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_keccak_256(a: bytes, pad_size: uint64) -> bytes: +verify_keccak_256: + // tests/artifacts/CryptoOps/contract.py:17-18 + // @arc4.abimethod() + // def verify_keccak_256(self, a: Bytes, pad_size: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/CryptoOps/contract.py:19 + // a = op.bzero(pad_size) + a + frame_dig -1 + bzero + frame_dig -2 + concat + dup + frame_bury -2 + // tests/artifacts/CryptoOps/contract.py:20 + // result = op.keccak256(a) + keccak256 + // tests/artifacts/CryptoOps/contract.py:21 + // return result + retsub + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_sha512_256(a: bytes, pad_size: uint64) -> bytes: +verify_sha512_256: + // tests/artifacts/CryptoOps/contract.py:23-24 + // @arc4.abimethod() + // def verify_sha512_256(self, a: Bytes, pad_size: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/CryptoOps/contract.py:25 + // a = op.bzero(pad_size) + a + frame_dig -1 + bzero + frame_dig -2 + concat + dup + frame_bury -2 + // tests/artifacts/CryptoOps/contract.py:26 + // result = op.sha512_256(a) + sha512_256 + // tests/artifacts/CryptoOps/contract.py:27 + // return result + retsub + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ed25519verify(a: bytes, b: bytes, c: bytes) -> bytes: +verify_ed25519verify: + // tests/artifacts/CryptoOps/contract.py:29-30 + // @arc4.abimethod() + // def verify_ed25519verify(self, a: Bytes, b: Bytes, c: Bytes) -> arc4.Bool: + proto 3 1 + // tests/artifacts/CryptoOps/contract.py:31 + // ensure_budget(1900, OpUpFeeSource.GroupCredit) + int 1900 + int 0 + callsub ensure_budget + // tests/artifacts/CryptoOps/contract.py:32 + // result = op.ed25519verify(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + ed25519verify + // tests/artifacts/CryptoOps/contract.py:33 + // return arc4.Bool(result) + byte 0x00 + int 0 + uncover 2 + setbit + retsub + + +// algopy.ensure_budget(required_budget: uint64, fee_source: uint64) -> void: +ensure_budget: + // /algopy.py:11-17 + proto 2 0 + // /algopy.py:18 + frame_dig -2 + int 10 + + + +ensure_budget_while_top@1: + // /algopy.py:19 + frame_dig 0 + global OpcodeBudget + > + bz ensure_budget_after_while@7 + // /algopy.py:20 + itxn_begin + // /algopy.py:21 + int appl + itxn_field TypeEnum + // /algopy.py:22 + int DeleteApplication + itxn_field OnCompletion + // /algopy.py:23 + byte 0x068101 + itxn_field ApprovalProgram + // /algopy.py:24 + byte 0x068101 + itxn_field ClearStateProgram + // /algopy.py:25-29 + 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: + // /algopy.py:27 + int 0 + itxn_field Fee + b ensure_budget_switch_case_next@6 + +ensure_budget_switch_case_1@4: + // /algopy.py:29 + global MinTxnFee + itxn_field Fee + +ensure_budget_switch_case_next@6: + // /algopy.py:30 + itxn_submit + b ensure_budget_while_top@1 + +ensure_budget_after_while@7: + retsub + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ed25519verify_bare(a: bytes, b: bytes, c: bytes) -> bytes: +verify_ed25519verify_bare: + // tests/artifacts/CryptoOps/contract.py:35-36 + // @arc4.abimethod() + // def verify_ed25519verify_bare(self, a: Bytes, b: Bytes, c: Bytes) -> arc4.Bool: + proto 3 1 + // tests/artifacts/CryptoOps/contract.py:37 + // ensure_budget(1900, OpUpFeeSource.GroupCredit) + int 1900 + int 0 + callsub ensure_budget + // tests/artifacts/CryptoOps/contract.py:38 + // result = op.ed25519verify_bare(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + ed25519verify_bare + // tests/artifacts/CryptoOps/contract.py:39 + // return arc4.Bool(result) + byte 0x00 + int 0 + uncover 2 + setbit + retsub + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_verify_k1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes) -> uint64: +verify_ecdsa_verify_k1: + // tests/artifacts/CryptoOps/contract.py:41-42 + // @arc4.abimethod() + // def verify_ecdsa_verify_k1(self, a: Bytes, b: Bytes, c: Bytes, d: Bytes, e: Bytes) -> bool: + proto 5 1 + // tests/artifacts/CryptoOps/contract.py:43 + // ensure_budget(3000, OpUpFeeSource.GroupCredit) + int 3000 + int 0 + callsub ensure_budget + // tests/artifacts/CryptoOps/contract.py:44 + // result_k1 = op.ecdsa_verify(op.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/CryptoOps/contract.py:45 + // return result_k1 + retsub + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_verify_r1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes) -> uint64: +verify_ecdsa_verify_r1: + // tests/artifacts/CryptoOps/contract.py:47-48 + // @arc4.abimethod() + // def verify_ecdsa_verify_r1(self, a: Bytes, b: Bytes, c: Bytes, d: Bytes, e: Bytes) -> bool: + proto 5 1 + // tests/artifacts/CryptoOps/contract.py:49 + // ensure_budget(3000, OpUpFeeSource.GroupCredit) + int 3000 + int 0 + callsub ensure_budget + // tests/artifacts/CryptoOps/contract.py:50 + // result_r1 = op.ecdsa_verify(op.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/CryptoOps/contract.py:51 + // return result_r1 + retsub + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_recover_k1(a: bytes, b: uint64, c: bytes, d: bytes) -> bytes, bytes: +verify_ecdsa_recover_k1: + // tests/artifacts/CryptoOps/contract.py:53-56 + // @arc4.abimethod() + // def verify_ecdsa_recover_k1( + // self, a: Bytes, b: UInt64, c: Bytes, d: Bytes + // ) -> tuple[Bytes, Bytes]: + proto 4 2 + // tests/artifacts/CryptoOps/contract.py:57 + // ensure_budget(3000, OpUpFeeSource.GroupCredit) + int 3000 + int 0 + callsub ensure_budget + // tests/artifacts/CryptoOps/contract.py:58 + // return op.ecdsa_pk_recover(op.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.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_recover_r1(a: bytes, b: uint64, c: bytes, d: bytes) -> bytes, bytes: +verify_ecdsa_recover_r1: + // tests/artifacts/CryptoOps/contract.py:60-63 + // @arc4.abimethod() + // def verify_ecdsa_recover_r1( + // self, a: Bytes, b: UInt64, c: Bytes, d: Bytes + // ) -> tuple[Bytes, Bytes]: + proto 4 2 + // tests/artifacts/CryptoOps/contract.py:67 + // ensure_budget(3000, OpUpFeeSource.GroupCredit) + int 3000 + int 0 + callsub ensure_budget + // tests/artifacts/CryptoOps/contract.py:68 + // return op.ecdsa_pk_recover(op.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.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_decompress_k1(a: bytes) -> bytes, bytes: +verify_ecdsa_decompress_k1: + // tests/artifacts/CryptoOps/contract.py:70-71 + // @arc4.abimethod() + // def verify_ecdsa_decompress_k1(self, a: Bytes) -> tuple[Bytes, Bytes]: + proto 1 2 + // tests/artifacts/CryptoOps/contract.py:72 + // ensure_budget(700, OpUpFeeSource.GroupCredit) + int 700 + int 0 + callsub ensure_budget + // tests/artifacts/CryptoOps/contract.py:73 + // return op.ecdsa_pk_decompress(op.ECDSA.Secp256k1, a) + frame_dig -1 + ecdsa_pk_decompress Secp256k1 + retsub + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_decompress_r1(a: bytes) -> bytes, bytes: +verify_ecdsa_decompress_r1: + // tests/artifacts/CryptoOps/contract.py:75-76 + // @arc4.abimethod() + // def verify_ecdsa_decompress_r1(self, a: Bytes) -> tuple[Bytes, Bytes]: + proto 1 2 + // tests/artifacts/CryptoOps/contract.py:77 + // ensure_budget(700, OpUpFeeSource.GroupCredit) + int 700 + int 0 + callsub ensure_budget + // tests/artifacts/CryptoOps/contract.py:78 + // return op.ecdsa_pk_decompress(op.ECDSA.Secp256r1, a) + frame_dig -1 + ecdsa_pk_decompress Secp256r1 + retsub + + +// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_vrf_verify(a: bytes, b: bytes, c: bytes) -> bytes, uint64: +verify_vrf_verify: + // tests/artifacts/CryptoOps/contract.py:80-81 + // @arc4.abimethod() + // def verify_vrf_verify(self, a: Bytes, b: Bytes, c: Bytes) -> tuple[Bytes, bool]: + proto 3 2 + // tests/artifacts/CryptoOps/contract.py:82 + // ensure_budget(5700, OpUpFeeSource.GroupCredit) + int 5700 + int 0 + callsub ensure_budget + // tests/artifacts/CryptoOps/contract.py:83 + // result = op.vrf_verify(op.VrfVerify.VrfAlgorand, a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + vrf_verify VrfAlgorand + // tests/artifacts/CryptoOps/contract.py:84 + // return result + retsub diff --git a/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc32.json b/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc32.json new file mode 100644 index 0000000..007f9f8 --- /dev/null +++ b/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc32.json @@ -0,0 +1,368 @@ +{ + "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": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuQ3J5cHRvT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdAMTcKICAgIG1ldGhvZCAidmVyaWZ5X3NoYTI1NihieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X3NoYTNfMjU2KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfa2VjY2FrXzI1NihieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X3NoYTUxMl8yNTYoYnl0ZVtdLHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9lZDI1NTE5dmVyaWZ5KGJ5dGVbXSxieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmUoYnl0ZVtdLGJ5dGVbXSxieXRlW10pYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2VjZHNhX3ZlcmlmeV9rMShieXRlW10sYnl0ZVtdLGJ5dGVbXSxieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9lY2RzYV92ZXJpZnlfcjEoYnl0ZVtdLGJ5dGVbXSxieXRlW10sYnl0ZVtdLGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMShieXRlW10sdWludDY0LGJ5dGVbXSxieXRlW10pKGJ5dGVbXSxieXRlW10pIgogICAgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMShieXRlW10sdWludDY0LGJ5dGVbXSxieXRlW10pKGJ5dGVbXSxieXRlW10pIgogICAgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMShieXRlW10pKGJ5dGVbXSxieXRlW10pIgogICAgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMShieXRlW10pKGJ5dGVbXSxieXRlW10pIgogICAgbWV0aG9kICJ2ZXJpZnlfdnJmX3ZlcmlmeShieXRlW10sYnl0ZVtdLGJ5dGVbXSkoYnl0ZVtdLGJvb2wpIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl92ZXJpZnlfc2hhMjU2X3JvdXRlQDIgbWFpbl92ZXJpZnlfc2hhM18yNTZfcm91dGVAMyBtYWluX3ZlcmlmeV9rZWNjYWtfMjU2X3JvdXRlQDQgbWFpbl92ZXJpZnlfc2hhNTEyXzI1Nl9yb3V0ZUA1IG1haW5fdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfcm91dGVANiBtYWluX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmVfcm91dGVANyBtYWluX3ZlcmlmeV9lY2RzYV92ZXJpZnlfazFfcm91dGVAOCBtYWluX3ZlcmlmeV9lY2RzYV92ZXJpZnlfcjFfcm91dGVAOSBtYWluX3ZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxX3JvdXRlQDEwIG1haW5fdmVyaWZ5X2VjZHNhX3JlY292ZXJfcjFfcm91dGVAMTEgbWFpbl92ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMV9yb3V0ZUAxMiBtYWluX3ZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX3IxX3JvdXRlQDEzIG1haW5fdmVyaWZ5X3ZyZl92ZXJpZnlfcm91dGVAMTQKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X3NoYTI1Nl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NoYTI1NgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3NoYTNfMjU2X3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGEzXzI1NgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2tlY2Nha18yNTZfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2tlY2Nha18yNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zaGE1MTJfMjU2X3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGE1MTJfMjU2CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZWQyNTUxOXZlcmlmeV9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lZDI1NTE5dmVyaWZ5CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmVfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWQyNTUxOXZlcmlmeV9iYXJlCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9lY2RzYV92ZXJpZnlfazFfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV92ZXJpZnlfazEKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9lY2RzYV92ZXJpZnlfcjFfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV92ZXJpZnlfcjEKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaW50IDQKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBieXRlIDB4MDAwNAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMQogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGludCA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZSAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazFfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX2sxCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaW50IDQKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBieXRlIDB4MDAwNAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMV9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjEKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBpbnQgNAogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGJ5dGUgMHgwMDA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV92cmZfdmVyaWZ5X3JvdXRlQDE0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6ODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV92cmZfdmVyaWZ5CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgwMDAzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfc2hhMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTI1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NS02CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9zaGEyNTYoc2VsZiwgYTogQnl0ZXMsIHBhZF9zaXplOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjcKICAgIC8vIGEgPSBvcC5iemVybyhwYWRfc2l6ZSkgKyBhCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgZHVwCiAgICBmcmFtZV9idXJ5IC0yCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjgKICAgIC8vIHJlc3VsdCA9IG9wLnNoYTI1NihhKQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5DcnlwdG9PcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X3NoYTNfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTNfMjU2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToxMS0xMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2hhM18yNTYoc2VsZiwgYTogQnl0ZXMsIHBhZF9zaXplOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjEzCiAgICAvLyBhID0gb3AuYnplcm8ocGFkX3NpemUpICsgYQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIGR1cAogICAgZnJhbWVfYnVyeSAtMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToxNAogICAgLy8gcmVzdWx0ID0gb3Auc2hhM18yNTYoYSkKICAgIHNoYTNfMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjE1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuQ3J5cHRvT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9rZWNjYWtfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2tlY2Nha18yNTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjE3LTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9rZWNjYWtfMjU2KHNlbGYsIGE6IEJ5dGVzLCBwYWRfc2l6ZTogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToxOQogICAgLy8gYSA9IG9wLmJ6ZXJvKHBhZF9zaXplKSArIGEKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgLTIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MjAKICAgIC8vIHJlc3VsdCA9IG9wLmtlY2NhazI1NihhKQogICAga2VjY2FrMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjIxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuQ3J5cHRvT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9zaGE1MTJfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTUxMl8yNTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjIzLTI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9zaGE1MTJfMjU2KHNlbGYsIGE6IEJ5dGVzLCBwYWRfc2l6ZTogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToyNQogICAgLy8gYSA9IG9wLmJ6ZXJvKHBhZF9zaXplKSArIGEKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgLTIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MjYKICAgIC8vIHJlc3VsdCA9IG9wLnNoYTUxMl8yNTYoYSkKICAgIHNoYTUxMl8yNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MjcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5DcnlwdG9PcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VkMjU1MTl2ZXJpZnkoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9lZDI1NTE5dmVyaWZ5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToyOS0zMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZWQyNTUxOXZlcmlmeShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMsIGM6IEJ5dGVzKSAtPiBhcmM0LkJvb2w6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MzEKICAgIC8vIGVuc3VyZV9idWRnZXQoMTkwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludCAxOTAwCiAgICBpbnQgMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjMyCiAgICAvLyByZXN1bHQgPSBvcC5lZDI1NTE5dmVyaWZ5KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlZDI1NTE5dmVyaWZ5CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjMzCiAgICAvLyByZXR1cm4gYXJjNC5Cb29sKHJlc3VsdCkKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICByZXRzdWIKCgovLyBhbGdvcHkuZW5zdXJlX2J1ZGdldChyZXF1aXJlZF9idWRnZXQ6IHVpbnQ2NCwgZmVlX3NvdXJjZTogdWludDY0KSAtPiB2b2lkOgplbnN1cmVfYnVkZ2V0OgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjExLTE3CiAgICBwcm90byAyIDAKICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToxOAogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMTAKICAgICsKCmVuc3VyZV9idWRnZXRfd2hpbGVfdG9wQDE6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MTkKICAgIGZyYW1lX2RpZyAwCiAgICBnbG9iYWwgT3Bjb2RlQnVkZ2V0CiAgICA+CiAgICBieiBlbnN1cmVfYnVkZ2V0X2FmdGVyX3doaWxlQDcKICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToyMAogICAgaXR4bl9iZWdpbgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjIxCiAgICBpbnQgYXBwbAogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjIyCiAgICBpbnQgRGVsZXRlQXBwbGljYXRpb24KICAgIGl0eG5fZmllbGQgT25Db21wbGV0aW9uCiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjMKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQXBwcm92YWxQcm9ncmFtCiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjQKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToyNS0yOQogICAgZnJhbWVfZGlnIC0xCiAgICBzd2l0Y2ggZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8wQDMgZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8xQDQKICAgIGIgZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDYKCmVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMEAzOgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjI3CiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIGIgZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDYKCmVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMUA0OgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjI5CiAgICBnbG9iYWwgTWluVHhuRmVlCiAgICBpdHhuX2ZpZWxkIEZlZQoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDY6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MzAKICAgIGl0eG5fc3VibWl0CiAgICBiIGVuc3VyZV9idWRnZXRfd2hpbGVfdG9wQDEKCmVuc3VyZV9idWRnZXRfYWZ0ZXJfd2hpbGVANzoKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5DcnlwdG9PcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MzUtMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMsIGM6IEJ5dGVzKSAtPiBhcmM0LkJvb2w6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MzcKICAgIC8vIGVuc3VyZV9idWRnZXQoMTkwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludCAxOTAwCiAgICBpbnQgMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjM4CiAgICAvLyByZXN1bHQgPSBvcC5lZDI1NTE5dmVyaWZ5X2JhcmUoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGVkMjU1MTl2ZXJpZnlfYmFyZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTozOQogICAgLy8gcmV0dXJuIGFyYzQuQm9vbChyZXN1bHQpCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMsIGQ6IGJ5dGVzLCBlOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0MS00MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgYzogQnl0ZXMsIGQ6IEJ5dGVzLCBlOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDUgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0MwogICAgLy8gZW5zdXJlX2J1ZGdldCgzMDAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDMwMDAKICAgIGludCAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NDQKICAgIC8vIHJlc3VsdF9rMSA9IG9wLmVjZHNhX3ZlcmlmeShvcC5FQ0RTQS5TZWNwMjU2azEsIGEsIGIsIGMsIGQsIGUpCiAgICBmcmFtZV9kaWcgLTUKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWNkc2FfdmVyaWZ5IFNlY3AyNTZrMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0NQogICAgLy8gcmV0dXJuIHJlc3VsdF9rMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMsIGQ6IGJ5dGVzLCBlOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0Ny00OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgYzogQnl0ZXMsIGQ6IEJ5dGVzLCBlOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDUgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0OQogICAgLy8gZW5zdXJlX2J1ZGdldCgzMDAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDMwMDAKICAgIGludCAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NTAKICAgIC8vIHJlc3VsdF9yMSA9IG9wLmVjZHNhX3ZlcmlmeShvcC5FQ0RTQS5TZWNwMjU2cjEsIGEsIGIsIGMsIGQsIGUpCiAgICBmcmFtZV9kaWcgLTUKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWNkc2FfdmVyaWZ5IFNlY3AyNTZyMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo1MQogICAgLy8gcmV0dXJuIHJlc3VsdF9yMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMShhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzLCBieXRlczoKdmVyaWZ5X2VjZHNhX3JlY292ZXJfazE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjUzLTU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxKAogICAgLy8gICAgIHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQsIGM6IEJ5dGVzLCBkOiBCeXRlcwogICAgLy8gKSAtPiB0dXBsZVtCeXRlcywgQnl0ZXNdOgogICAgcHJvdG8gNCAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjU3CiAgICAvLyBlbnN1cmVfYnVkZ2V0KDMwMDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgMzAwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo1OAogICAgLy8gcmV0dXJuIG9wLmVjZHNhX3BrX3JlY292ZXIob3AuRUNEU0EuU2VjcDI1NmsxLCBhLCBiLCBjLCBkKQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19yZWNvdmVyIFNlY3AyNTZrMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMShhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzLCBieXRlczoKdmVyaWZ5X2VjZHNhX3JlY292ZXJfcjE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjYwLTYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxKAogICAgLy8gICAgIHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQsIGM6IEJ5dGVzLCBkOiBCeXRlcwogICAgLy8gKSAtPiB0dXBsZVtCeXRlcywgQnl0ZXNdOgogICAgcHJvdG8gNCAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjY3CiAgICAvLyBlbnN1cmVfYnVkZ2V0KDMwMDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgMzAwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo2OAogICAgLy8gcmV0dXJuIG9wLmVjZHNhX3BrX3JlY292ZXIob3AuRUNEU0EuU2VjcDI1NnIxLCBhLCBiLCBjLCBkKQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19yZWNvdmVyIFNlY3AyNTZyMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzAtNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazEoc2VsZiwgYTogQnl0ZXMpIC0+IHR1cGxlW0J5dGVzLCBCeXRlc106CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzIKICAgIC8vIGVuc3VyZV9idWRnZXQoNzAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDcwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo3MwogICAgLy8gcmV0dXJuIG9wLmVjZHNhX3BrX2RlY29tcHJlc3Mob3AuRUNEU0EuU2VjcDI1NmsxLCBhKQogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19kZWNvbXByZXNzIFNlY3AyNTZrMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzUtNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjEoc2VsZiwgYTogQnl0ZXMpIC0+IHR1cGxlW0J5dGVzLCBCeXRlc106CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzcKICAgIC8vIGVuc3VyZV9idWRnZXQoNzAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDcwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo3OAogICAgLy8gcmV0dXJuIG9wLmVjZHNhX3BrX2RlY29tcHJlc3Mob3AuRUNEU0EuU2VjcDI1NnIxLCBhKQogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19kZWNvbXByZXNzIFNlY3AyNTZyMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfdnJmX3ZlcmlmeShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlcywgdWludDY0Ogp2ZXJpZnlfdnJmX3ZlcmlmeToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6ODAtODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3ZyZl92ZXJpZnkoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzLCBjOiBCeXRlcykgLT4gdHVwbGVbQnl0ZXMsIGJvb2xdOgogICAgcHJvdG8gMyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjgyCiAgICAvLyBlbnN1cmVfYnVkZ2V0KDU3MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgNTcwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo4MwogICAgLy8gcmVzdWx0ID0gb3AudnJmX3ZlcmlmeShvcC5WcmZWZXJpZnkuVnJmQWxnb3JhbmQsIGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICB2cmZfdmVyaWZ5IFZyZkFsZ29yYW5kCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5Ojg0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuQ3J5cHRvT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + }, + "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[])" + }, + "desc": "Must fail, AVM does not support Secp256r1 for recover" + }, + { + "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.clear.teal b/tests/artifacts/crypto-ops/data/CryptoOpsContract.clear.teal new file mode 100644 index 0000000..e1705b2 --- /dev/null +++ b/tests/artifacts/crypto-ops/data/CryptoOpsContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.CryptoOps.contract.CryptoOpsContract.clear_state_program: + // tests/artifacts/CryptoOps/contract.py:4 + // class CryptoOpsContract(ARC4Contract): + int 1 + return diff --git a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal new file mode 100644 index 0000000..070046d --- /dev/null +++ b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal @@ -0,0 +1,1699 @@ +#pragma version 10 + +tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.approval_program: + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@41 + 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_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[]" + method "verify_json_ref_string(byte[],byte[])byte[]" + method "verify_json_ref_uint64(byte[],byte[])uint64" + method "verify_json_ref_object(byte[],byte[])byte[]" + txna ApplicationArgs 0 + match main_verify_addw_route@2 main_verify_base64_decode_standard_route@3 main_verify_base64_decode_url_route@4 main_verify_bytes_bitlen_route@5 main_verify_uint64_bitlen_route@6 main_verify_bsqrt_route@7 main_verify_btoi_route@8 main_verify_bzero_route@9 main_verify_concat_route@10 main_verify_divmodw_route@11 main_verify_divw_route@12 main_verify_err_route@13 main_verify_exp_route@14 main_verify_expw_route@15 main_verify_extract_route@16 main_verify_extract_from_2_route@17 main_verify_extract_uint16_route@18 main_verify_extract_uint32_route@19 main_verify_extract_uint64_route@20 main_verify_getbit_bytes_route@21 main_verify_getbit_uint64_route@22 main_verify_getbyte_route@23 main_verify_itob_route@24 main_verify_mulw_route@25 main_verify_replace_route@26 main_verify_select_bytes_route@27 main_verify_select_uint64_route@28 main_verify_setbit_bytes_route@29 main_verify_setbit_uint64_route@30 main_verify_setbyte_route@31 main_verify_shl_route@32 main_verify_shr_route@33 main_verify_sqrt_route@34 main_verify_substring_route@35 main_verify_json_ref_string_route@36 main_verify_json_ref_uint64_route@37 main_verify_json_ref_object_route@38 + err // reject transaction + +main_verify_addw_route@2: + // tests/artifacts/MiscellaneousOps/contract.py:5 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:5 + // @arc4.abimethod() + callsub verify_addw + swap + itob + swap + itob + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_base64_decode_standard_route@3: + // tests/artifacts/MiscellaneousOps/contract.py:10 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/MiscellaneousOps/contract.py:10 + // @arc4.abimethod() + callsub verify_base64_decode_standard + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_base64_decode_url_route@4: + // tests/artifacts/MiscellaneousOps/contract.py:15 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/MiscellaneousOps/contract.py:15 + // @arc4.abimethod() + callsub verify_base64_decode_url + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bytes_bitlen_route@5: + // tests/artifacts/MiscellaneousOps/contract.py:20 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:20 + // @arc4.abimethod() + callsub verify_bytes_bitlen + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_bitlen_route@6: + // tests/artifacts/MiscellaneousOps/contract.py:26 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:26 + // @arc4.abimethod() + callsub verify_uint64_bitlen + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bsqrt_route@7: + // tests/artifacts/MiscellaneousOps/contract.py:31 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/MiscellaneousOps/contract.py:31 + // @arc4.abimethod() + callsub verify_bsqrt + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_btoi_route@8: + // tests/artifacts/MiscellaneousOps/contract.py:37 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/MiscellaneousOps/contract.py:37 + // @arc4.abimethod() + callsub verify_btoi + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bzero_route@9: + // tests/artifacts/MiscellaneousOps/contract.py:42 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:42 + // @arc4.abimethod() + callsub verify_bzero + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_concat_route@10: + // tests/artifacts/MiscellaneousOps/contract.py:47 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + btoi + txna ApplicationArgs 4 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:47 + // @arc4.abimethod() + callsub verify_concat + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_divmodw_route@11: + // tests/artifacts/MiscellaneousOps/contract.py:55 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + btoi + txna ApplicationArgs 4 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:55 + // @arc4.abimethod() + callsub verify_divmodw + cover 3 + cover 2 + swap + itob + cover 2 + itob + swap + itob + swap + uncover 3 + itob + cover 3 + uncover 2 + swap + concat + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_divw_route@12: + // tests/artifacts/MiscellaneousOps/contract.py:62 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:62 + // @arc4.abimethod() + callsub verify_divw + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_err_route@13: + // tests/artifacts/MiscellaneousOps/contract.py:67 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + callsub verify_err + int 1 + return + +main_verify_exp_route@14: + // tests/artifacts/MiscellaneousOps/contract.py:71 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:71 + // @arc4.abimethod() + callsub verify_exp + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_expw_route@15: + // tests/artifacts/MiscellaneousOps/contract.py:76 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:76 + // @arc4.abimethod() + callsub verify_expw + swap + itob + swap + itob + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_extract_route@16: + // tests/artifacts/MiscellaneousOps/contract.py:81 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:81 + // @arc4.abimethod() + callsub verify_extract + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_extract_from_2_route@17: + // tests/artifacts/MiscellaneousOps/contract.py:86 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/MiscellaneousOps/contract.py:86 + // @arc4.abimethod() + callsub verify_extract_from_2 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_extract_uint16_route@18: + // tests/artifacts/MiscellaneousOps/contract.py:91 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:91 + // @arc4.abimethod() + callsub verify_extract_uint16 + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_extract_uint32_route@19: + // tests/artifacts/MiscellaneousOps/contract.py:96 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:96 + // @arc4.abimethod() + callsub verify_extract_uint32 + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_extract_uint64_route@20: + // tests/artifacts/MiscellaneousOps/contract.py:101 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:101 + // @arc4.abimethod() + callsub verify_extract_uint64 + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_getbit_bytes_route@21: + // tests/artifacts/MiscellaneousOps/contract.py:106 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:106 + // @arc4.abimethod() + callsub verify_getbit_bytes + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_getbit_uint64_route@22: + // tests/artifacts/MiscellaneousOps/contract.py:111 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:111 + // @arc4.abimethod() + callsub verify_getbit_uint64 + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_getbyte_route@23: + // tests/artifacts/MiscellaneousOps/contract.py:116 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:116 + // @arc4.abimethod() + callsub verify_getbyte + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_itob_route@24: + // tests/artifacts/MiscellaneousOps/contract.py:121 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:121 + // @arc4.abimethod() + callsub verify_itob + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_mulw_route@25: + // tests/artifacts/MiscellaneousOps/contract.py:126 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:126 + // @arc4.abimethod() + callsub verify_mulw + swap + itob + swap + itob + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_replace_route@26: + // tests/artifacts/MiscellaneousOps/contract.py:131 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + extract 2 0 + // tests/artifacts/MiscellaneousOps/contract.py:131 + // @arc4.abimethod() + callsub verify_replace + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_select_bytes_route@27: + // tests/artifacts/MiscellaneousOps/contract.py:136 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:136 + // @arc4.abimethod() + callsub verify_select_bytes + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_select_uint64_route@28: + // tests/artifacts/MiscellaneousOps/contract.py:141 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:141 + // @arc4.abimethod() + callsub verify_select_uint64 + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_setbit_bytes_route@29: + // tests/artifacts/MiscellaneousOps/contract.py:146 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:146 + // @arc4.abimethod() + callsub verify_setbit_bytes + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_setbit_uint64_route@30: + // tests/artifacts/MiscellaneousOps/contract.py:151 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:151 + // @arc4.abimethod() + callsub verify_setbit_uint64 + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_setbyte_route@31: + // tests/artifacts/MiscellaneousOps/contract.py:156 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:156 + // @arc4.abimethod() + callsub verify_setbyte + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_shl_route@32: + // tests/artifacts/MiscellaneousOps/contract.py:161 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:161 + // @arc4.abimethod() + callsub verify_shl + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_shr_route@33: + // tests/artifacts/MiscellaneousOps/contract.py:166 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:166 + // @arc4.abimethod() + callsub verify_shr + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_sqrt_route@34: + // tests/artifacts/MiscellaneousOps/contract.py:171 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:171 + // @arc4.abimethod() + callsub verify_sqrt + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_substring_route@35: + // tests/artifacts/MiscellaneousOps/contract.py:176 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 3 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:176 + // @arc4.abimethod() + callsub verify_substring + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_json_ref_string_route@36: + // tests/artifacts/MiscellaneousOps/contract.py:181 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/MiscellaneousOps/contract.py:181 + // @arc4.abimethod() + callsub verify_json_ref_string + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_json_ref_uint64_route@37: + // tests/artifacts/MiscellaneousOps/contract.py:186 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/MiscellaneousOps/contract.py:186 + // @arc4.abimethod() + callsub verify_json_ref_uint64 + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_json_ref_object_route@38: + // tests/artifacts/MiscellaneousOps/contract.py:191 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/MiscellaneousOps/contract.py:191 + // @arc4.abimethod() + callsub verify_json_ref_object + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@41: + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_addw(a: uint64, b: uint64) -> uint64, uint64: +verify_addw: + // tests/artifacts/MiscellaneousOps/contract.py:5-6 + // @arc4.abimethod() + // def verify_addw(self, a: UInt64, b: UInt64) -> tuple[UInt64, UInt64]: + proto 2 2 + // tests/artifacts/MiscellaneousOps/contract.py:7 + // result = op.addw(a, b) + frame_dig -2 + frame_dig -1 + addw + // tests/artifacts/MiscellaneousOps/contract.py:8 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_base64_decode_standard(a: bytes) -> bytes: +verify_base64_decode_standard: + // tests/artifacts/MiscellaneousOps/contract.py:10-11 + // @arc4.abimethod() + // def verify_base64_decode_standard(self, a: Bytes) -> Bytes: + proto 1 1 + // tests/artifacts/MiscellaneousOps/contract.py:12 + // result = op.base64_decode(op.Base64.StdEncoding, a) + frame_dig -1 + base64_decode StdEncoding + // tests/artifacts/MiscellaneousOps/contract.py:13 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_base64_decode_url(a: bytes) -> bytes: +verify_base64_decode_url: + // tests/artifacts/MiscellaneousOps/contract.py:15-16 + // @arc4.abimethod() + // def verify_base64_decode_url(self, a: Bytes) -> Bytes: + proto 1 1 + // tests/artifacts/MiscellaneousOps/contract.py:17 + // result = op.base64_decode(op.Base64.URLEncoding, a) + frame_dig -1 + base64_decode URLEncoding + // tests/artifacts/MiscellaneousOps/contract.py:18 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_bytes_bitlen(a: bytes, pad_a_size: uint64) -> uint64: +verify_bytes_bitlen: + // tests/artifacts/MiscellaneousOps/contract.py:20-21 + // @arc4.abimethod() + // def verify_bytes_bitlen(self, a: Bytes, pad_a_size: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:22 + // a = op.bzero(pad_a_size) + a + frame_dig -1 + bzero + frame_dig -2 + concat + dup + frame_bury -2 + // tests/artifacts/MiscellaneousOps/contract.py:23 + // result = op.bitlen(a) + bitlen + // tests/artifacts/MiscellaneousOps/contract.py:24 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_uint64_bitlen(a: uint64) -> uint64: +verify_uint64_bitlen: + // tests/artifacts/MiscellaneousOps/contract.py:26-27 + // @arc4.abimethod() + // def verify_uint64_bitlen(self, a: UInt64) -> UInt64: + proto 1 1 + // tests/artifacts/MiscellaneousOps/contract.py:28 + // result = op.bitlen(a) + frame_dig -1 + bitlen + // tests/artifacts/MiscellaneousOps/contract.py:29 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_bsqrt(a: bytes) -> bytes: +verify_bsqrt: + // tests/artifacts/MiscellaneousOps/contract.py:31-32 + // @arc4.abimethod() + // def verify_bsqrt(self, a: Bytes) -> Bytes: + proto 1 1 + // tests/artifacts/MiscellaneousOps/contract.py:34 + // result = op.bsqrt(a_biguint) + frame_dig -1 + bsqrt + // tests/artifacts/MiscellaneousOps/contract.py:35 + // return result.bytes + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_btoi(a: bytes) -> uint64: +verify_btoi: + // tests/artifacts/MiscellaneousOps/contract.py:37-38 + // @arc4.abimethod() + // def verify_btoi(self, a: Bytes) -> UInt64: + proto 1 1 + // tests/artifacts/MiscellaneousOps/contract.py:39 + // result = op.btoi(a) + frame_dig -1 + btoi + // tests/artifacts/MiscellaneousOps/contract.py:40 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_bzero(a: uint64) -> bytes: +verify_bzero: + // tests/artifacts/MiscellaneousOps/contract.py:42-43 + // @arc4.abimethod() + // def verify_bzero(self, a: UInt64) -> Bytes: + proto 1 1 + // tests/artifacts/MiscellaneousOps/contract.py:44 + // result = op.bzero(a) + frame_dig -1 + bzero + // tests/artifacts/MiscellaneousOps/contract.py:45 + // return op.sha256(result) + sha256 + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_concat(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64) -> bytes: +verify_concat: + // tests/artifacts/MiscellaneousOps/contract.py:47-48 + // @arc4.abimethod() + // def verify_concat(self, a: Bytes, b: Bytes, pad_a_size: UInt64, pad_b_size: UInt64) -> Bytes: + proto 4 1 + // tests/artifacts/MiscellaneousOps/contract.py:49 + // a = op.bzero(pad_a_size) + a + frame_dig -2 + bzero + frame_dig -4 + concat + frame_bury -4 + // tests/artifacts/MiscellaneousOps/contract.py:50 + // b = op.bzero(pad_b_size) + b + frame_dig -1 + bzero + frame_dig -3 + concat + frame_bury -3 + // tests/artifacts/MiscellaneousOps/contract.py:51 + // result = a + b + frame_dig -4 + frame_dig -3 + concat + // tests/artifacts/MiscellaneousOps/contract.py:52 + // result = op.sha256(result) + sha256 + // tests/artifacts/MiscellaneousOps/contract.py:53 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_divmodw(a: uint64, b: uint64, c: uint64, d: uint64) -> uint64, uint64, uint64, uint64: +verify_divmodw: + // tests/artifacts/MiscellaneousOps/contract.py:55-58 + // @arc4.abimethod() + // def verify_divmodw( + // self, a: UInt64, b: UInt64, c: UInt64, d: UInt64 + // ) -> tuple[UInt64, UInt64, UInt64, UInt64]: + proto 4 4 + // tests/artifacts/MiscellaneousOps/contract.py:59 + // result = op.divmodw(a, b, c, d) + frame_dig -4 + frame_dig -3 + frame_dig -2 + frame_dig -1 + divmodw + // tests/artifacts/MiscellaneousOps/contract.py:60 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_divw(a: uint64, b: uint64, c: uint64) -> uint64: +verify_divw: + // tests/artifacts/MiscellaneousOps/contract.py:62-63 + // @arc4.abimethod() + // def verify_divw(self, a: UInt64, b: UInt64, c: UInt64) -> UInt64: + proto 3 1 + // tests/artifacts/MiscellaneousOps/contract.py:64 + // result = op.divw(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + divw + // tests/artifacts/MiscellaneousOps/contract.py:65 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_err() -> void: +verify_err: + // tests/artifacts/MiscellaneousOps/contract.py:67-68 + // @arc4.abimethod() + // def verify_err(self) -> None: + proto 0 0 + // tests/artifacts/MiscellaneousOps/contract.py:69 + // op.err() + err + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_exp(a: uint64, b: uint64) -> uint64: +verify_exp: + // tests/artifacts/MiscellaneousOps/contract.py:71-72 + // @arc4.abimethod() + // def verify_exp(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:73 + // result = op.exp(a, b) + frame_dig -2 + frame_dig -1 + exp + // tests/artifacts/MiscellaneousOps/contract.py:74 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_expw(a: uint64, b: uint64) -> uint64, uint64: +verify_expw: + // tests/artifacts/MiscellaneousOps/contract.py:76-77 + // @arc4.abimethod() + // def verify_expw(self, a: UInt64, b: UInt64) -> tuple[UInt64, UInt64]: + proto 2 2 + // tests/artifacts/MiscellaneousOps/contract.py:78 + // result = op.expw(a, b) + frame_dig -2 + frame_dig -1 + expw + // tests/artifacts/MiscellaneousOps/contract.py:79 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_extract(a: bytes, b: uint64, c: uint64) -> bytes: +verify_extract: + // tests/artifacts/MiscellaneousOps/contract.py:81-82 + // @arc4.abimethod() + // def verify_extract(self, a: Bytes, b: UInt64, c: UInt64) -> Bytes: + proto 3 1 + // tests/artifacts/MiscellaneousOps/contract.py:83 + // result = op.extract(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + extract3 + // tests/artifacts/MiscellaneousOps/contract.py:84 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_extract_from_2(a: bytes) -> bytes: +verify_extract_from_2: + // tests/artifacts/MiscellaneousOps/contract.py:86-87 + // @arc4.abimethod() + // def verify_extract_from_2(self, a: Bytes) -> Bytes: + proto 1 1 + // tests/artifacts/MiscellaneousOps/contract.py:88 + // result = op.extract(a, 2, 0) + frame_dig -1 + extract 2 0 + // tests/artifacts/MiscellaneousOps/contract.py:89 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_extract_uint16(a: bytes, b: uint64) -> uint64: +verify_extract_uint16: + // tests/artifacts/MiscellaneousOps/contract.py:91-92 + // @arc4.abimethod() + // def verify_extract_uint16(self, a: Bytes, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:93 + // result = op.extract_uint16(a, b) + frame_dig -2 + frame_dig -1 + extract_uint16 + // tests/artifacts/MiscellaneousOps/contract.py:94 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_extract_uint32(a: bytes, b: uint64) -> uint64: +verify_extract_uint32: + // tests/artifacts/MiscellaneousOps/contract.py:96-97 + // @arc4.abimethod() + // def verify_extract_uint32(self, a: Bytes, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:98 + // result = op.extract_uint32(a, b) + frame_dig -2 + frame_dig -1 + extract_uint32 + // tests/artifacts/MiscellaneousOps/contract.py:99 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_extract_uint64(a: bytes, b: uint64) -> uint64: +verify_extract_uint64: + // tests/artifacts/MiscellaneousOps/contract.py:101-102 + // @arc4.abimethod() + // def verify_extract_uint64(self, a: Bytes, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:103 + // result = op.extract_uint64(a, b) + frame_dig -2 + frame_dig -1 + extract_uint64 + // tests/artifacts/MiscellaneousOps/contract.py:104 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_getbit_bytes(a: bytes, b: uint64) -> uint64: +verify_getbit_bytes: + // tests/artifacts/MiscellaneousOps/contract.py:106-107 + // @arc4.abimethod() + // def verify_getbit_bytes(self, a: Bytes, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:108 + // result = op.getbit(a, b) + frame_dig -2 + frame_dig -1 + getbit + // tests/artifacts/MiscellaneousOps/contract.py:109 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_getbit_uint64(a: uint64, b: uint64) -> uint64: +verify_getbit_uint64: + // tests/artifacts/MiscellaneousOps/contract.py:111-112 + // @arc4.abimethod() + // def verify_getbit_uint64(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:113 + // result = op.getbit(a, b) + frame_dig -2 + frame_dig -1 + getbit + // tests/artifacts/MiscellaneousOps/contract.py:114 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_getbyte(a: bytes, b: uint64) -> uint64: +verify_getbyte: + // tests/artifacts/MiscellaneousOps/contract.py:116-117 + // @arc4.abimethod() + // def verify_getbyte(self, a: Bytes, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:118 + // result = op.getbyte(a, b) + frame_dig -2 + frame_dig -1 + getbyte + // tests/artifacts/MiscellaneousOps/contract.py:119 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_itob(a: uint64) -> bytes: +verify_itob: + // tests/artifacts/MiscellaneousOps/contract.py:121-122 + // @arc4.abimethod() + // def verify_itob(self, a: UInt64) -> Bytes: + proto 1 1 + // tests/artifacts/MiscellaneousOps/contract.py:123 + // result = op.itob(a) + frame_dig -1 + itob + // tests/artifacts/MiscellaneousOps/contract.py:124 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_mulw(a: uint64, b: uint64) -> uint64, uint64: +verify_mulw: + // tests/artifacts/MiscellaneousOps/contract.py:126-127 + // @arc4.abimethod() + // def verify_mulw(self, a: UInt64, b: UInt64) -> tuple[UInt64, UInt64]: + proto 2 2 + // tests/artifacts/MiscellaneousOps/contract.py:128 + // result = op.mulw(a, b) + frame_dig -2 + frame_dig -1 + mulw + // tests/artifacts/MiscellaneousOps/contract.py:129 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_replace(a: bytes, b: uint64, c: bytes) -> bytes: +verify_replace: + // tests/artifacts/MiscellaneousOps/contract.py:131-132 + // @arc4.abimethod() + // def verify_replace(self, a: Bytes, b: UInt64, c: Bytes) -> Bytes: + proto 3 1 + // tests/artifacts/MiscellaneousOps/contract.py:133 + // result = op.replace(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + replace3 + // tests/artifacts/MiscellaneousOps/contract.py:134 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_select_bytes(a: bytes, b: bytes, c: uint64) -> bytes: +verify_select_bytes: + // tests/artifacts/MiscellaneousOps/contract.py:136-137 + // @arc4.abimethod() + // def verify_select_bytes(self, a: Bytes, b: Bytes, c: UInt64) -> Bytes: + proto 3 1 + // tests/artifacts/MiscellaneousOps/contract.py:138 + // result = op.select_bytes(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + select + // tests/artifacts/MiscellaneousOps/contract.py:139 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_select_uint64(a: uint64, b: uint64, c: uint64) -> uint64: +verify_select_uint64: + // tests/artifacts/MiscellaneousOps/contract.py:141-142 + // @arc4.abimethod() + // def verify_select_uint64(self, a: UInt64, b: UInt64, c: UInt64) -> UInt64: + proto 3 1 + // tests/artifacts/MiscellaneousOps/contract.py:143 + // result = op.select_uint64(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + select + // tests/artifacts/MiscellaneousOps/contract.py:144 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_setbit_bytes(a: bytes, b: uint64, c: uint64) -> bytes: +verify_setbit_bytes: + // tests/artifacts/MiscellaneousOps/contract.py:146-147 + // @arc4.abimethod() + // def verify_setbit_bytes(self, a: Bytes, b: UInt64, c: UInt64) -> Bytes: + proto 3 1 + // tests/artifacts/MiscellaneousOps/contract.py:148 + // result = op.setbit_bytes(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + setbit + // tests/artifacts/MiscellaneousOps/contract.py:149 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_setbit_uint64(a: uint64, b: uint64, c: uint64) -> uint64: +verify_setbit_uint64: + // tests/artifacts/MiscellaneousOps/contract.py:151-152 + // @arc4.abimethod() + // def verify_setbit_uint64(self, a: UInt64, b: UInt64, c: UInt64) -> UInt64: + proto 3 1 + // tests/artifacts/MiscellaneousOps/contract.py:153 + // result = op.setbit_uint64(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + setbit + // tests/artifacts/MiscellaneousOps/contract.py:154 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_setbyte(a: bytes, b: uint64, c: uint64) -> bytes: +verify_setbyte: + // tests/artifacts/MiscellaneousOps/contract.py:156-157 + // @arc4.abimethod() + // def verify_setbyte(self, a: Bytes, b: UInt64, c: UInt64) -> Bytes: + proto 3 1 + // tests/artifacts/MiscellaneousOps/contract.py:158 + // result = op.setbyte(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + setbyte + // tests/artifacts/MiscellaneousOps/contract.py:159 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_shl(a: uint64, b: uint64) -> uint64: +verify_shl: + // tests/artifacts/MiscellaneousOps/contract.py:161-162 + // @arc4.abimethod() + // def verify_shl(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:163 + // result = op.shl(a, b) + frame_dig -2 + frame_dig -1 + shl + // tests/artifacts/MiscellaneousOps/contract.py:164 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_shr(a: uint64, b: uint64) -> uint64: +verify_shr: + // tests/artifacts/MiscellaneousOps/contract.py:166-167 + // @arc4.abimethod() + // def verify_shr(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:168 + // result = op.shr(a, b) + frame_dig -2 + frame_dig -1 + shr + // tests/artifacts/MiscellaneousOps/contract.py:169 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_sqrt(a: uint64) -> uint64: +verify_sqrt: + // tests/artifacts/MiscellaneousOps/contract.py:171-172 + // @arc4.abimethod() + // def verify_sqrt(self, a: UInt64) -> UInt64: + proto 1 1 + // tests/artifacts/MiscellaneousOps/contract.py:173 + // result = op.sqrt(a) + frame_dig -1 + sqrt + // tests/artifacts/MiscellaneousOps/contract.py:174 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_substring(a: bytes, b: uint64, c: uint64) -> bytes: +verify_substring: + // tests/artifacts/MiscellaneousOps/contract.py:176-177 + // @arc4.abimethod() + // def verify_substring(self, a: Bytes, b: UInt64, c: UInt64) -> Bytes: + proto 3 1 + // tests/artifacts/MiscellaneousOps/contract.py:178 + // result = op.substring(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + substring3 + // tests/artifacts/MiscellaneousOps/contract.py:179 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_json_ref_string(a: bytes, b: bytes) -> bytes: +verify_json_ref_string: + // tests/artifacts/MiscellaneousOps/contract.py:181-182 + // @arc4.abimethod() + // def verify_json_ref_string(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:183 + // result = op.JsonRef.json_string(a, b) + frame_dig -2 + frame_dig -1 + json_ref JSONString + // tests/artifacts/MiscellaneousOps/contract.py:184 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_json_ref_uint64(a: bytes, b: bytes) -> uint64: +verify_json_ref_uint64: + // tests/artifacts/MiscellaneousOps/contract.py:186-187 + // @arc4.abimethod() + // def verify_json_ref_uint64(self, a: Bytes, b: Bytes) -> UInt64: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:188 + // result = op.JsonRef.json_uint64(a, b) + frame_dig -2 + frame_dig -1 + json_ref JSONUint64 + // tests/artifacts/MiscellaneousOps/contract.py:189 + // return result + retsub + + +// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_json_ref_object(a: bytes, b: bytes) -> bytes: +verify_json_ref_object: + // tests/artifacts/MiscellaneousOps/contract.py:191-192 + // @arc4.abimethod() + // def verify_json_ref_object(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/MiscellaneousOps/contract.py:193 + // result = op.JsonRef.json_object(a, b) + frame_dig -2 + frame_dig -1 + json_ref JSONObject + // tests/artifacts/MiscellaneousOps/contract.py:194 + // return result + retsub diff --git a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json new file mode 100644 index 0000000..8a3e7d8 --- /dev/null +++ b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json @@ -0,0 +1,858 @@ +{ + "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_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" + } + }, + "verify_json_ref_string(byte[],byte[])byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_json_ref_uint64(byte[],byte[])uint64": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_json_ref_object(byte[],byte[])byte[]": { + "call_config": { + "no_op": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDQxCiAgICBtZXRob2QgInZlcmlmeV9hZGR3KHVpbnQ2NCx1aW50NjQpKHVpbnQ2NCx1aW50NjQpIgogICAgbWV0aG9kICJ2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZChieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmFzZTY0X2RlY29kZV91cmwoYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2J5dGVzX2JpdGxlbihieXRlW10sdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9iaXRsZW4odWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2JzcXJ0KGJ5dGVbXSlieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9idG9pKGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9iemVybyh1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfY29uY2F0KGJ5dGVbXSxieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9kaXZtb2R3KHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCkodWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0KSIKICAgIG1ldGhvZCAidmVyaWZ5X2RpdncodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfZXJyKCl2b2lkIgogICAgbWV0aG9kICJ2ZXJpZnlfZXhwKHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfZXhwdyh1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0KSIKICAgIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3QoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF9mcm9tXzIoYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3RfdWludDE2KGJ5dGVbXSx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF91aW50MzIoYnl0ZVtdLHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9leHRyYWN0X3VpbnQ2NChieXRlW10sdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2dldGJpdF9ieXRlcyhieXRlW10sdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2dldGJpdF91aW50NjQodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9nZXRieXRlKGJ5dGVbXSx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfaXRvYih1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfbXVsdyh1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0KSIKICAgIG1ldGhvZCAidmVyaWZ5X3JlcGxhY2UoYnl0ZVtdLHVpbnQ2NCxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfc2VsZWN0X2J5dGVzKGJ5dGVbXSxieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X3NlbGVjdF91aW50NjQodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfc2V0Yml0X2J5dGVzKGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X3NldGJpdF91aW50NjQodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfc2V0Ynl0ZShieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9zaGwodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9zaHIodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9zcXJ0KHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9zdWJzdHJpbmcoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfanNvbl9yZWZfc3RyaW5nKGJ5dGVbXSxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfanNvbl9yZWZfdWludDY0KGJ5dGVbXSxieXRlW10pdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfanNvbl9yZWZfb2JqZWN0KGJ5dGVbXSxieXRlW10pYnl0ZVtdIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl92ZXJpZnlfYWRkd19yb3V0ZUAyIG1haW5fdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmRfcm91dGVAMyBtYWluX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybF9yb3V0ZUA0IG1haW5fdmVyaWZ5X2J5dGVzX2JpdGxlbl9yb3V0ZUA1IG1haW5fdmVyaWZ5X3VpbnQ2NF9iaXRsZW5fcm91dGVANiBtYWluX3ZlcmlmeV9ic3FydF9yb3V0ZUA3IG1haW5fdmVyaWZ5X2J0b2lfcm91dGVAOCBtYWluX3ZlcmlmeV9iemVyb19yb3V0ZUA5IG1haW5fdmVyaWZ5X2NvbmNhdF9yb3V0ZUAxMCBtYWluX3ZlcmlmeV9kaXZtb2R3X3JvdXRlQDExIG1haW5fdmVyaWZ5X2Rpdndfcm91dGVAMTIgbWFpbl92ZXJpZnlfZXJyX3JvdXRlQDEzIG1haW5fdmVyaWZ5X2V4cF9yb3V0ZUAxNCBtYWluX3ZlcmlmeV9leHB3X3JvdXRlQDE1IG1haW5fdmVyaWZ5X2V4dHJhY3Rfcm91dGVAMTYgbWFpbl92ZXJpZnlfZXh0cmFjdF9mcm9tXzJfcm91dGVAMTcgbWFpbl92ZXJpZnlfZXh0cmFjdF91aW50MTZfcm91dGVAMTggbWFpbl92ZXJpZnlfZXh0cmFjdF91aW50MzJfcm91dGVAMTkgbWFpbl92ZXJpZnlfZXh0cmFjdF91aW50NjRfcm91dGVAMjAgbWFpbl92ZXJpZnlfZ2V0Yml0X2J5dGVzX3JvdXRlQDIxIG1haW5fdmVyaWZ5X2dldGJpdF91aW50NjRfcm91dGVAMjIgbWFpbl92ZXJpZnlfZ2V0Ynl0ZV9yb3V0ZUAyMyBtYWluX3ZlcmlmeV9pdG9iX3JvdXRlQDI0IG1haW5fdmVyaWZ5X211bHdfcm91dGVAMjUgbWFpbl92ZXJpZnlfcmVwbGFjZV9yb3V0ZUAyNiBtYWluX3ZlcmlmeV9zZWxlY3RfYnl0ZXNfcm91dGVAMjcgbWFpbl92ZXJpZnlfc2VsZWN0X3VpbnQ2NF9yb3V0ZUAyOCBtYWluX3ZlcmlmeV9zZXRiaXRfYnl0ZXNfcm91dGVAMjkgbWFpbl92ZXJpZnlfc2V0Yml0X3VpbnQ2NF9yb3V0ZUAzMCBtYWluX3ZlcmlmeV9zZXRieXRlX3JvdXRlQDMxIG1haW5fdmVyaWZ5X3NobF9yb3V0ZUAzMiBtYWluX3ZlcmlmeV9zaHJfcm91dGVAMzMgbWFpbl92ZXJpZnlfc3FydF9yb3V0ZUAzNCBtYWluX3ZlcmlmeV9zdWJzdHJpbmdfcm91dGVAMzUgbWFpbl92ZXJpZnlfanNvbl9yZWZfc3RyaW5nX3JvdXRlQDM2IG1haW5fdmVyaWZ5X2pzb25fcmVmX3VpbnQ2NF9yb3V0ZUAzNyBtYWluX3ZlcmlmeV9qc29uX3JlZl9vYmplY3Rfcm91dGVAMzgKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X2FkZHdfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hZGR3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmRfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmFzZTY0X2RlY29kZV91cmxfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX2JpdGxlbl9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2JpdGxlbgogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludDY0X2JpdGxlbl9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2JpdGxlbgogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnNxcnRfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjMxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ic3FydAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J0b2lfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9idG9pCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iemVyb19yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnplcm8KICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9jb25jYXRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2NvbmNhdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Rpdm1vZHdfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo1NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9kaXZtb2R3CiAgICBjb3ZlciAzCiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb3ZlciAyCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIGNvdmVyIDMKICAgIHVuY292ZXIgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZGl2d19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2RpdncKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Vycl9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiB2ZXJpZnlfZXJyCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9leHBfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHAKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2V4cHdfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHB3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2V4dHJhY3Rfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXh0cmFjdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2V4dHJhY3RfZnJvbV8yX3JvdXRlQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6ODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo4NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfZnJvbV8yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZXh0cmFjdF91aW50MTZfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXh0cmFjdF91aW50MTYKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2V4dHJhY3RfdWludDMyX3JvdXRlQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6OTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfdWludDMyCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9leHRyYWN0X3VpbnQ2NF9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfdWludDY0CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRiaXRfYnl0ZXNfcm91dGVAMjE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRiaXRfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldGJpdF91aW50NjRfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjExMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldGJpdF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldGJ5dGVfcm91dGVAMjM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRieXRlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9pdG9iX3JvdXRlQDI0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9pdG9iCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfbXVsd19yb3V0ZUAyNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEyNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfbXVsdwogICAgc3dhcAogICAgaXRvYgogICAgc3dhcAogICAgaXRvYgogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9yZXBsYWNlX3JvdXRlQDI2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTMxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3JlcGxhY2UKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zZWxlY3RfYnl0ZXNfcm91dGVAMjc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTM2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2VsZWN0X2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2VsZWN0X3VpbnQ2NF9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2VsZWN0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2V0Yml0X2J5dGVzX3JvdXRlQDI5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2V0Yml0X2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2V0Yml0X3VpbnQ2NF9yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2V0Yml0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2V0Ynl0ZV9yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NldGJ5dGUKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zaGxfcm91dGVAMzI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NobAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2hyX3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaHIKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3NxcnRfcm91dGVAMzQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NxcnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3N1YnN0cmluZ19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N1YnN0cmluZwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2pzb25fcmVmX3N0cmluZ19yb3V0ZUAzNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9qc29uX3JlZl9zdHJpbmcKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9qc29uX3JlZl91aW50NjRfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfanNvbl9yZWZfdWludDY0CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9qc29uX3JlZl9vYmplY3Rfcm91dGVAMzg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxOTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTkxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfanNvbl9yZWZfb2JqZWN0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdANDE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2FkZHcoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfYWRkdzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjUtNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWRkdyhzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gdHVwbGVbVUludDY0LCBVSW50NjRdOgogICAgcHJvdG8gMiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo3CiAgICAvLyByZXN1bHQgPSBvcC5hZGR3KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYWRkdwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6OAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMC0xMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZChzZWxmLCBhOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEyCiAgICAvLyByZXN1bHQgPSBvcC5iYXNlNjRfZGVjb2RlKG9wLkJhc2U2NC5TdGRFbmNvZGluZywgYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYmFzZTY0X2RlY29kZSBTdGRFbmNvZGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfYmFzZTY0X2RlY29kZV91cmwoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmFzZTY0X2RlY29kZV91cmw6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNS0xNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmFzZTY0X2RlY29kZV91cmwoc2VsZiwgYTogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNwogICAgLy8gcmVzdWx0ID0gb3AuYmFzZTY0X2RlY29kZShvcC5CYXNlNjQuVVJMRW5jb2RpbmcsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhc2U2NF9kZWNvZGUgVVJMRW5jb2RpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE4CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2JpdGxlbihhOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlc19iaXRsZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToyMC0yMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnl0ZXNfYml0bGVuKHNlbGYsIGE6IEJ5dGVzLCBwYWRfYV9zaXplOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MjIKICAgIC8vIGEgPSBvcC5iemVybyhwYWRfYV9zaXplKSArIGEKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgLTIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjIzCiAgICAvLyByZXN1bHQgPSBvcC5iaXRsZW4oYSkKICAgIGJpdGxlbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2JpdGxlbihhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9iaXRsZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToyNi0yNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2JpdGxlbihzZWxmLCBhOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MjgKICAgIC8vIHJlc3VsdCA9IG9wLmJpdGxlbihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiaXRsZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjI5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2JzcXJ0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JzcXJ0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MzEtMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JzcXJ0KHNlbGYsIGE6IEJ5dGVzKSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MzQKICAgIC8vIHJlc3VsdCA9IG9wLmJzcXJ0KGFfYmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgYnNxcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjM1CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J0b2koYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J0b2k6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTozNy0zOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnRvaShzZWxmLCBhOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTozOQogICAgLy8gcmVzdWx0ID0gb3AuYnRvaShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0MAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iemVybyhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYnplcm86CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0Mi00MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnplcm8oc2VsZiwgYTogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NDQKICAgIC8vIHJlc3VsdCA9IG9wLmJ6ZXJvKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0NQogICAgLy8gcmV0dXJuIG9wLnNoYTI1NihyZXN1bHQpCiAgICBzaGEyNTYKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfY29uY2F0KGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfY29uY2F0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NDctNDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2NvbmNhdChzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMsIHBhZF9hX3NpemU6IFVJbnQ2NCwgcGFkX2Jfc2l6ZTogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDQgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NDkKICAgIC8vIGEgPSBvcC5iemVybyhwYWRfYV9zaXplKSArIGEKICAgIGZyYW1lX2RpZyAtMgogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtNAogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IC00CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo1MAogICAgLy8gYiA9IG9wLmJ6ZXJvKHBhZF9iX3NpemUpICsgYgogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIGZyYW1lX2J1cnkgLTMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjUxCiAgICAvLyByZXN1bHQgPSBhICsgYgogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NTIKICAgIC8vIHJlc3VsdCA9IG9wLnNoYTI1NihyZXN1bHQpCiAgICBzaGEyNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjUzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2Rpdm1vZHcoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCwgZDogdWludDY0KSAtPiB1aW50NjQsIHVpbnQ2NCwgdWludDY0LCB1aW50NjQ6CnZlcmlmeV9kaXZtb2R3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NTUtNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Rpdm1vZHcoCiAgICAvLyAgICAgc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQsIGM6IFVJbnQ2NCwgZDogVUludDY0CiAgICAvLyApIC0+IHR1cGxlW1VJbnQ2NCwgVUludDY0LCBVSW50NjQsIFVJbnQ2NF06CiAgICBwcm90byA0IDQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjU5CiAgICAvLyByZXN1bHQgPSBvcC5kaXZtb2R3KGEsIGIsIGMsIGQpCiAgICBmcmFtZV9kaWcgLTQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGRpdm1vZHcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjYwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2RpdncoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZGl2dzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjYyLTYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9kaXZ3KHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0LCBjOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NjQKICAgIC8vIHJlc3VsdCA9IG9wLmRpdncoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGRpdncKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjY1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2VycigpIC0+IHZvaWQ6CnZlcmlmeV9lcnI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo2Ny02OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZXJyKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjY5CiAgICAvLyBvcC5lcnIoKQogICAgZXJyCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHAoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2V4cDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjcxLTcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9leHAoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzMKICAgIC8vIHJlc3VsdCA9IG9wLmV4cChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4cAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXhwdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQ6CnZlcmlmeV9leHB3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzYtNzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2V4cHcoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IHR1cGxlW1VJbnQ2NCwgVUludDY0XToKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzgKICAgIC8vIHJlc3VsdCA9IG9wLmV4cHcoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHB3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo3OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0KGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9leHRyYWN0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6ODEtODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2V4dHJhY3Qoc2VsZiwgYTogQnl0ZXMsIGI6IFVJbnQ2NCwgYzogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6ODMKICAgIC8vIHJlc3VsdCA9IG9wLmV4dHJhY3QoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo4NAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X2Zyb21fMihhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9leHRyYWN0X2Zyb21fMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5Ojg2LTg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9leHRyYWN0X2Zyb21fMihzZWxmLCBhOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5Ojg4CiAgICAvLyByZXN1bHQgPSBvcC5leHRyYWN0KGEsIDIsIDApCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo4OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQxNihhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjkxLTkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9leHRyYWN0X3VpbnQxNihzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjkzCiAgICAvLyByZXN1bHQgPSBvcC5leHRyYWN0X3VpbnQxNihhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3RfdWludDE2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo5NAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQzMihhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5Ojk2LTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9leHRyYWN0X3VpbnQzMihzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5Ojk4CiAgICAvLyByZXN1bHQgPSBvcC5leHRyYWN0X3VpbnQzMihhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3RfdWludDMyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo5OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwMS0xMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2V4dHJhY3RfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTAzCiAgICAvLyByZXN1bHQgPSBvcC5leHRyYWN0X3VpbnQ2NChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3RfdWludDY0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMDQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZ2V0Yml0X2J5dGVzKGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldGJpdF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwNi0xMDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2dldGJpdF9ieXRlcyhzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwOAogICAgLy8gcmVzdWx0ID0gb3AuZ2V0Yml0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZ2V0Yml0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMDkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZ2V0Yml0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0Yml0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjExMS0xMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2dldGJpdF91aW50NjQoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTEzCiAgICAvLyByZXN1bHQgPSBvcC5nZXRiaXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBnZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjExNAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9nZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldGJ5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMTYtMTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRieXRlKHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTE4CiAgICAvLyByZXN1bHQgPSBvcC5nZXRieXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZ2V0Ynl0ZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTE5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2l0b2IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2l0b2I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMjEtMTIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9pdG9iKHNlbGYsIGE6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEyMwogICAgLy8gcmVzdWx0ID0gb3AuaXRvYihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMjQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfbXVsdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQ6CnZlcmlmeV9tdWx3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTI2LTEyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfbXVsdyhzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gdHVwbGVbVUludDY0LCBVSW50NjRdOgogICAgcHJvdG8gMiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMjgKICAgIC8vIHJlc3VsdCA9IG9wLm11bHcoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBtdWx3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMjkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfcmVwbGFjZShhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9yZXBsYWNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTMxLTEzMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfcmVwbGFjZShzZWxmLCBhOiBCeXRlcywgYjogVUludDY0LCBjOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEzMwogICAgLy8gcmVzdWx0ID0gb3AucmVwbGFjZShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgcmVwbGFjZTMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEzNAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZWxlY3RfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc2VsZWN0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTM2LTEzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2VsZWN0X2J5dGVzKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgYzogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTM4CiAgICAvLyByZXN1bHQgPSBvcC5zZWxlY3RfYnl0ZXMoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNlbGVjdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTM5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NlbGVjdF91aW50NjQoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc2VsZWN0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE0MS0xNDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3NlbGVjdF91aW50NjQoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQsIGM6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNDMKICAgIC8vIHJlc3VsdCA9IG9wLnNlbGVjdF91aW50NjQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNlbGVjdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTQ0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NldGJpdF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc2V0Yml0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTQ2LTE0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2V0Yml0X2J5dGVzKHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQsIGM6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE0OAogICAgLy8gcmVzdWx0ID0gb3Auc2V0Yml0X2J5dGVzKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE0OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NldGJpdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNTEtMTUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9zZXRiaXRfdWludDY0KHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0LCBjOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyByZXN1bHQgPSBvcC5zZXRiaXRfdWludDY0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1NAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zZXRieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTU2LTE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2V0Ynl0ZShzZWxmLCBhOiBCeXRlcywgYjogVUludDY0LCBjOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNTgKICAgIC8vIHJlc3VsdCA9IG9wLnNldGJ5dGUoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNldGJ5dGUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zaGwoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NobDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE2MS0xNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3NobChzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNjMKICAgIC8vIHJlc3VsdCA9IG9wLnNobChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNobAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTY0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NocihhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc2hyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTY2LTE2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2hyKHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE2OAogICAgLy8gcmVzdWx0ID0gb3Auc2hyKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2hyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNjkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc3FydChhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NxcnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNzEtMTcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9zcXJ0KHNlbGYsIGE6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNzMKICAgIC8vIHJlc3VsdCA9IG9wLnNxcnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgc3FydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTc0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3N1YnN0cmluZyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc3Vic3RyaW5nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTc2LTE3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc3Vic3RyaW5nKHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQsIGM6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE3OAogICAgLy8gcmVzdWx0ID0gb3Auc3Vic3RyaW5nKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzdWJzdHJpbmczCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNzkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfanNvbl9yZWZfc3RyaW5nKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9qc29uX3JlZl9zdHJpbmc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxODEtMTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9qc29uX3JlZl9zdHJpbmcoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTgzCiAgICAvLyByZXN1bHQgPSBvcC5Kc29uUmVmLmpzb25fc3RyaW5nKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAganNvbl9yZWYgSlNPTlN0cmluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTg0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2pzb25fcmVmX3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2pzb25fcmVmX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE4Ni0xODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2pzb25fcmVmX3VpbnQ2NChzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTg4CiAgICAvLyByZXN1bHQgPSBvcC5Kc29uUmVmLmpzb25fdWludDY0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAganNvbl9yZWYgSlNPTlVpbnQ2NAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTg5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2pzb25fcmVmX29iamVjdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfanNvbl9yZWZfb2JqZWN0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTkxLTE5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfanNvbl9yZWZfb2JqZWN0KHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE5MwogICAgLy8gcmVzdWx0ID0gb3AuSnNvblJlZi5qc29uX29iamVjdChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGpzb25fcmVmIEpTT05PYmplY3QKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE5NAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + }, + "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_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[]" + } + }, + { + "name": "verify_json_ref_string", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "byte[]", + "name": "b" + } + ], + "readonly": false, + "returns": { + "type": "byte[]" + } + }, + { + "name": "verify_json_ref_uint64", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "byte[]", + "name": "b" + } + ], + "readonly": false, + "returns": { + "type": "uint64" + } + }, + { + "name": "verify_json_ref_object", + "args": [ + { + "type": "byte[]", + "name": "a" + }, + { + "type": "byte[]", + "name": "b" + } + ], + "readonly": false, + "returns": { + "type": "byte[]" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ 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 new file mode 100644 index 0000000..69f45be --- /dev/null +++ b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.clear_state_program: + // tests/artifacts/MiscellaneousOps/contract.py:4 + // class MiscellaneousOpsContract(ARC4Contract): + int 1 + return diff --git a/tests/artifacts/primitives/data/PrimitiveOpsContract.approval.teal b/tests/artifacts/primitives/data/PrimitiveOpsContract.approval.teal new file mode 100644 index 0000000..058b711 --- /dev/null +++ b/tests/artifacts/primitives/data/PrimitiveOpsContract.approval.teal @@ -0,0 +1,2885 @@ +#pragma version 10 + +tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.approval_program: + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@64 + 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_string_init(string)string" + method "verify_string_startswith(string,string)bool" + method "verify_string_endswith(string,string)bool" + method "verify_string_join(string,string)string" + method "verify_log(string,uint64,byte[],byte[],bool,string,uint64,uint256,ufixed32x8,ufixed256x16,byte[],byte[],byte[])void" + txna ApplicationArgs 0 + match main_verify_uint64_init_route@2 main_verify_uint64_add_route@3 main_verify_uint64_sub_route@4 main_verify_uint64_mul_route@5 main_verify_uint64_div_route@6 main_verify_uint64_mod_route@7 main_verify_uint64_and_route@8 main_verify_uint64_or_route@9 main_verify_uint64_xor_route@10 main_verify_uint64_not_route@11 main_verify_uint64_lshift_route@12 main_verify_uint64_rshift_route@13 main_verify_uint64_pow_route@14 main_verify_uint64_eq_route@15 main_verify_uint64_ne_route@16 main_verify_uint64_lt_route@17 main_verify_uint64_le_route@18 main_verify_uint64_gt_route@19 main_verify_uint64_ge_route@20 main_verify_bytes_init_route@21 main_verify_bytes_add_route@22 main_verify_bytes_eq_route@23 main_verify_bytes_ne_route@24 main_verify_bytes_and_route@25 main_verify_bytes_or_route@26 main_verify_bytes_xor_route@27 main_verify_bytes_not_route@28 main_verify_biguint_add_route@29 main_verify_biguint_add_uint64_route@30 main_verify_biguint_sub_route@31 main_verify_biguint_sub_uint64_route@32 main_verify_biguint_mul_route@33 main_verify_biguint_mul_uint64_route@34 main_verify_biguint_div_route@35 main_verify_biguint_div_uint64_route@36 main_verify_biguint_mod_route@37 main_verify_biguint_mod_uint64_route@38 main_verify_biguint_and_route@39 main_verify_biguint_and_uint64_route@40 main_verify_biguint_or_route@41 main_verify_biguint_or_uint64_route@42 main_verify_biguint_xor_route@43 main_verify_biguint_xor_uint64_route@44 main_verify_biguint_eq_route@45 main_verify_biguint_eq_uint64_route@46 main_verify_biguint_ne_route@47 main_verify_biguint_ne_uint64_route@48 main_verify_biguint_lt_route@49 main_verify_biguint_lt_uint64_route@50 main_verify_biguint_le_route@51 main_verify_biguint_le_uint64_route@52 main_verify_biguint_gt_route@53 main_verify_biguint_gt_uint64_route@54 main_verify_biguint_ge_route@55 main_verify_biguint_ge_uint64_route@56 main_verify_string_init_route@57 main_verify_string_startswith_route@58 main_verify_string_endswith_route@59 main_verify_string_join_route@60 main_verify_log_route@61 + err // reject transaction + +main_verify_uint64_init_route@2: + // tests/artifacts/PrimitiveOps/contract.py:7 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:7 + // @arc4.abimethod() + callsub verify_uint64_init + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_add_route@3: + // tests/artifacts/PrimitiveOps/contract.py:12 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:12 + // @arc4.abimethod() + callsub verify_uint64_add + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_sub_route@4: + // tests/artifacts/PrimitiveOps/contract.py:17 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:17 + // @arc4.abimethod() + callsub verify_uint64_sub + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_mul_route@5: + // tests/artifacts/PrimitiveOps/contract.py:22 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:22 + // @arc4.abimethod() + callsub verify_uint64_mul + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_div_route@6: + // tests/artifacts/PrimitiveOps/contract.py:27 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:27 + // @arc4.abimethod() + callsub verify_uint64_div + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_mod_route@7: + // tests/artifacts/PrimitiveOps/contract.py:32 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:32 + // @arc4.abimethod() + callsub verify_uint64_mod + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_and_route@8: + // tests/artifacts/PrimitiveOps/contract.py:37 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:37 + // @arc4.abimethod() + callsub verify_uint64_and + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_or_route@9: + // tests/artifacts/PrimitiveOps/contract.py:42 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:42 + // @arc4.abimethod() + callsub verify_uint64_or + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_xor_route@10: + // tests/artifacts/PrimitiveOps/contract.py:47 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:47 + // @arc4.abimethod() + callsub verify_uint64_xor + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_not_route@11: + // tests/artifacts/PrimitiveOps/contract.py:52 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + // tests/artifacts/PrimitiveOps/contract.py:52 + // @arc4.abimethod() + callsub verify_uint64_not + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_lshift_route@12: + // tests/artifacts/PrimitiveOps/contract.py:57 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:57 + // @arc4.abimethod() + callsub verify_uint64_lshift + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_rshift_route@13: + // tests/artifacts/PrimitiveOps/contract.py:62 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:62 + // @arc4.abimethod() + callsub verify_uint64_rshift + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_pow_route@14: + // tests/artifacts/PrimitiveOps/contract.py:67 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:67 + // @arc4.abimethod() + callsub verify_uint64_pow + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_eq_route@15: + // tests/artifacts/PrimitiveOps/contract.py:72 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:72 + // @arc4.abimethod() + callsub verify_uint64_eq + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_ne_route@16: + // tests/artifacts/PrimitiveOps/contract.py:77 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:77 + // @arc4.abimethod() + callsub verify_uint64_ne + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_lt_route@17: + // tests/artifacts/PrimitiveOps/contract.py:82 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:82 + // @arc4.abimethod() + callsub verify_uint64_lt + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_le_route@18: + // tests/artifacts/PrimitiveOps/contract.py:87 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:87 + // @arc4.abimethod() + callsub verify_uint64_le + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_gt_route@19: + // tests/artifacts/PrimitiveOps/contract.py:92 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:92 + // @arc4.abimethod() + callsub verify_uint64_gt + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_uint64_ge_route@20: + // tests/artifacts/PrimitiveOps/contract.py:97 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:97 + // @arc4.abimethod() + callsub verify_uint64_ge + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bytes_init_route@21: + // tests/artifacts/PrimitiveOps/contract.py:102 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + // tests/artifacts/PrimitiveOps/contract.py:102 + // @arc4.abimethod() + callsub verify_bytes_init + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bytes_add_route@22: + // tests/artifacts/PrimitiveOps/contract.py:107 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + btoi + txna ApplicationArgs 4 + btoi + // tests/artifacts/PrimitiveOps/contract.py:107 + // @arc4.abimethod() + callsub verify_bytes_add + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bytes_eq_route@23: + // tests/artifacts/PrimitiveOps/contract.py:117 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:117 + // @arc4.abimethod() + callsub verify_bytes_eq + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bytes_ne_route@24: + // tests/artifacts/PrimitiveOps/contract.py:122 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:122 + // @arc4.abimethod() + callsub verify_bytes_ne + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bytes_and_route@25: + // tests/artifacts/PrimitiveOps/contract.py:127 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:127 + // @arc4.abimethod() + callsub verify_bytes_and + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bytes_or_route@26: + // tests/artifacts/PrimitiveOps/contract.py:132 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:132 + // @arc4.abimethod() + callsub verify_bytes_or + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bytes_xor_route@27: + // tests/artifacts/PrimitiveOps/contract.py:137 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:137 + // @arc4.abimethod() + callsub verify_bytes_xor + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_bytes_not_route@28: + // tests/artifacts/PrimitiveOps/contract.py:142 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:142 + // @arc4.abimethod() + callsub verify_bytes_not + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_add_route@29: + // tests/artifacts/PrimitiveOps/contract.py:149 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:149 + // @arc4.abimethod() + callsub verify_biguint_add + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_add_uint64_route@30: + // tests/artifacts/PrimitiveOps/contract.py:156 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:156 + // @arc4.abimethod() + callsub verify_biguint_add_uint64 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_sub_route@31: + // tests/artifacts/PrimitiveOps/contract.py:162 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:162 + // @arc4.abimethod() + callsub verify_biguint_sub + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_sub_uint64_route@32: + // tests/artifacts/PrimitiveOps/contract.py:169 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:169 + // @arc4.abimethod() + callsub verify_biguint_sub_uint64 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_mul_route@33: + // tests/artifacts/PrimitiveOps/contract.py:175 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:175 + // @arc4.abimethod() + callsub verify_biguint_mul + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_mul_uint64_route@34: + // tests/artifacts/PrimitiveOps/contract.py:182 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:182 + // @arc4.abimethod() + callsub verify_biguint_mul_uint64 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_div_route@35: + // tests/artifacts/PrimitiveOps/contract.py:188 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:188 + // @arc4.abimethod() + callsub verify_biguint_div + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_div_uint64_route@36: + // tests/artifacts/PrimitiveOps/contract.py:195 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:195 + // @arc4.abimethod() + callsub verify_biguint_div_uint64 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_mod_route@37: + // tests/artifacts/PrimitiveOps/contract.py:201 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:201 + // @arc4.abimethod() + callsub verify_biguint_mod + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_mod_uint64_route@38: + // tests/artifacts/PrimitiveOps/contract.py:208 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:208 + // @arc4.abimethod() + callsub verify_biguint_mod_uint64 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_and_route@39: + // tests/artifacts/PrimitiveOps/contract.py:214 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:214 + // @arc4.abimethod() + callsub verify_biguint_and + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_and_uint64_route@40: + // tests/artifacts/PrimitiveOps/contract.py:221 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:221 + // @arc4.abimethod() + callsub verify_biguint_and_uint64 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_or_route@41: + // tests/artifacts/PrimitiveOps/contract.py:227 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:227 + // @arc4.abimethod() + callsub verify_biguint_or + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_or_uint64_route@42: + // tests/artifacts/PrimitiveOps/contract.py:234 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:234 + // @arc4.abimethod() + callsub verify_biguint_or_uint64 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_xor_route@43: + // tests/artifacts/PrimitiveOps/contract.py:240 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:240 + // @arc4.abimethod() + callsub verify_biguint_xor + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_xor_uint64_route@44: + // tests/artifacts/PrimitiveOps/contract.py:247 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:247 + // @arc4.abimethod() + callsub verify_biguint_xor_uint64 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_eq_route@45: + // tests/artifacts/PrimitiveOps/contract.py:253 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:253 + // @arc4.abimethod() + callsub verify_biguint_eq + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_eq_uint64_route@46: + // tests/artifacts/PrimitiveOps/contract.py:260 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:260 + // @arc4.abimethod() + callsub verify_biguint_eq_uint64 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_ne_route@47: + // tests/artifacts/PrimitiveOps/contract.py:266 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:266 + // @arc4.abimethod() + callsub verify_biguint_ne + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_ne_uint64_route@48: + // tests/artifacts/PrimitiveOps/contract.py:273 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:273 + // @arc4.abimethod() + callsub verify_biguint_ne_uint64 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_lt_route@49: + // tests/artifacts/PrimitiveOps/contract.py:279 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:279 + // @arc4.abimethod() + callsub verify_biguint_lt + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_lt_uint64_route@50: + // tests/artifacts/PrimitiveOps/contract.py:286 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:286 + // @arc4.abimethod() + callsub verify_biguint_lt_uint64 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_le_route@51: + // tests/artifacts/PrimitiveOps/contract.py:292 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:292 + // @arc4.abimethod() + callsub verify_biguint_le + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_le_uint64_route@52: + // tests/artifacts/PrimitiveOps/contract.py:299 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:299 + // @arc4.abimethod() + callsub verify_biguint_le_uint64 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_gt_route@53: + // tests/artifacts/PrimitiveOps/contract.py:305 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:305 + // @arc4.abimethod() + callsub verify_biguint_gt + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_gt_uint64_route@54: + // tests/artifacts/PrimitiveOps/contract.py:312 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:312 + // @arc4.abimethod() + callsub verify_biguint_gt_uint64 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_ge_route@55: + // tests/artifacts/PrimitiveOps/contract.py:318 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:318 + // @arc4.abimethod() + callsub verify_biguint_ge + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_biguint_ge_uint64_route@56: + // tests/artifacts/PrimitiveOps/contract.py:325 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/PrimitiveOps/contract.py:325 + // @arc4.abimethod() + callsub verify_biguint_ge_uint64 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_string_init_route@57: + // tests/artifacts/PrimitiveOps/contract.py:331 + // @arc4.abimethod + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:331 + // @arc4.abimethod + callsub verify_string_init + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_string_startswith_route@58: + // tests/artifacts/PrimitiveOps/contract.py:336 + // @arc4.abimethod + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:336 + // @arc4.abimethod + callsub verify_string_startswith + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_string_endswith_route@59: + // tests/artifacts/PrimitiveOps/contract.py:341 + // @arc4.abimethod + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:341 + // @arc4.abimethod + callsub verify_string_endswith + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_string_join_route@60: + // tests/artifacts/PrimitiveOps/contract.py:346 + // @arc4.abimethod + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/PrimitiveOps/contract.py:346 + // @arc4.abimethod + callsub verify_string_join + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_log_route@61: + // tests/artifacts/PrimitiveOps/contract.py:351 + // @arc4.abimethod + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + 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/PrimitiveOps/contract.py:351 + // @arc4.abimethod + callsub verify_log + int 1 + return + +main_bare_routing@64: + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_init(raw_value: bytes) -> uint64: +verify_uint64_init: + // tests/artifacts/PrimitiveOps/contract.py:7-8 + // @arc4.abimethod() + // def verify_uint64_init(self, raw_value: Bytes) -> UInt64: + proto 1 1 + // tests/artifacts/PrimitiveOps/contract.py:9 + // result = op.btoi(raw_value) + frame_dig -1 + btoi + // tests/artifacts/PrimitiveOps/contract.py:10 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_add(a: uint64, b: uint64) -> uint64: +verify_uint64_add: + // tests/artifacts/PrimitiveOps/contract.py:12-13 + // @arc4.abimethod() + // def verify_uint64_add(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:14 + // result = a + b + frame_dig -2 + frame_dig -1 + + + // tests/artifacts/PrimitiveOps/contract.py:15 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_sub(a: uint64, b: uint64) -> uint64: +verify_uint64_sub: + // tests/artifacts/PrimitiveOps/contract.py:17-18 + // @arc4.abimethod() + // def verify_uint64_sub(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:19 + // result = a - b + frame_dig -2 + frame_dig -1 + - + // tests/artifacts/PrimitiveOps/contract.py:20 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_mul(a: uint64, b: uint64) -> uint64: +verify_uint64_mul: + // tests/artifacts/PrimitiveOps/contract.py:22-23 + // @arc4.abimethod() + // def verify_uint64_mul(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:24 + // result = a * b + frame_dig -2 + frame_dig -1 + * + // tests/artifacts/PrimitiveOps/contract.py:25 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_div(a: uint64, b: uint64) -> uint64: +verify_uint64_div: + // tests/artifacts/PrimitiveOps/contract.py:27-28 + // @arc4.abimethod() + // def verify_uint64_div(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:29 + // result = a // b + frame_dig -2 + frame_dig -1 + / + // tests/artifacts/PrimitiveOps/contract.py:30 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_mod(a: uint64, b: uint64) -> uint64: +verify_uint64_mod: + // tests/artifacts/PrimitiveOps/contract.py:32-33 + // @arc4.abimethod() + // def verify_uint64_mod(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:34 + // result = a % b + frame_dig -2 + frame_dig -1 + % + // tests/artifacts/PrimitiveOps/contract.py:35 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_and(a: uint64, b: uint64) -> uint64: +verify_uint64_and: + // tests/artifacts/PrimitiveOps/contract.py:37-38 + // @arc4.abimethod() + // def verify_uint64_and(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:39 + // result = a & b + frame_dig -2 + frame_dig -1 + & + // tests/artifacts/PrimitiveOps/contract.py:40 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_or(a: uint64, b: uint64) -> uint64: +verify_uint64_or: + // tests/artifacts/PrimitiveOps/contract.py:42-43 + // @arc4.abimethod() + // def verify_uint64_or(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:44 + // result = a | b + frame_dig -2 + frame_dig -1 + | + // tests/artifacts/PrimitiveOps/contract.py:45 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_xor(a: uint64, b: uint64) -> uint64: +verify_uint64_xor: + // tests/artifacts/PrimitiveOps/contract.py:47-48 + // @arc4.abimethod() + // def verify_uint64_xor(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:49 + // result = a ^ b + frame_dig -2 + frame_dig -1 + ^ + // tests/artifacts/PrimitiveOps/contract.py:50 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_not(a: uint64) -> uint64: +verify_uint64_not: + // tests/artifacts/PrimitiveOps/contract.py:52-53 + // @arc4.abimethod() + // def verify_uint64_not(self, a: UInt64) -> UInt64: + proto 1 1 + // tests/artifacts/PrimitiveOps/contract.py:54 + // result = ~a + frame_dig -1 + ~ + // tests/artifacts/PrimitiveOps/contract.py:55 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_lshift(a: uint64, b: uint64) -> uint64: +verify_uint64_lshift: + // tests/artifacts/PrimitiveOps/contract.py:57-58 + // @arc4.abimethod() + // def verify_uint64_lshift(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:59 + // result = a << b + frame_dig -2 + frame_dig -1 + shl + // tests/artifacts/PrimitiveOps/contract.py:60 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_rshift(a: uint64, b: uint64) -> uint64: +verify_uint64_rshift: + // tests/artifacts/PrimitiveOps/contract.py:62-63 + // @arc4.abimethod() + // def verify_uint64_rshift(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:64 + // result = a >> b + frame_dig -2 + frame_dig -1 + shr + // tests/artifacts/PrimitiveOps/contract.py:65 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_pow(a: uint64, b: uint64) -> uint64: +verify_uint64_pow: + // tests/artifacts/PrimitiveOps/contract.py:67-68 + // @arc4.abimethod() + // def verify_uint64_pow(self, a: UInt64, b: UInt64) -> UInt64: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:69 + // result = a**b + frame_dig -2 + frame_dig -1 + exp + // tests/artifacts/PrimitiveOps/contract.py:70 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_eq(a: uint64, b: uint64) -> uint64: +verify_uint64_eq: + // tests/artifacts/PrimitiveOps/contract.py:72-73 + // @arc4.abimethod() + // def verify_uint64_eq(self, a: UInt64, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:74 + // result = a == b + frame_dig -2 + frame_dig -1 + == + // tests/artifacts/PrimitiveOps/contract.py:75 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_ne(a: uint64, b: uint64) -> uint64: +verify_uint64_ne: + // tests/artifacts/PrimitiveOps/contract.py:77-78 + // @arc4.abimethod() + // def verify_uint64_ne(self, a: UInt64, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:79 + // result = a != b + frame_dig -2 + frame_dig -1 + != + // tests/artifacts/PrimitiveOps/contract.py:80 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_lt(a: uint64, b: uint64) -> uint64: +verify_uint64_lt: + // tests/artifacts/PrimitiveOps/contract.py:82-83 + // @arc4.abimethod() + // def verify_uint64_lt(self, a: UInt64, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:84 + // result = a < b + frame_dig -2 + frame_dig -1 + < + // tests/artifacts/PrimitiveOps/contract.py:85 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_le(a: uint64, b: uint64) -> uint64: +verify_uint64_le: + // tests/artifacts/PrimitiveOps/contract.py:87-88 + // @arc4.abimethod() + // def verify_uint64_le(self, a: UInt64, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:89 + // result = a <= b + frame_dig -2 + frame_dig -1 + <= + // tests/artifacts/PrimitiveOps/contract.py:90 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_gt(a: uint64, b: uint64) -> uint64: +verify_uint64_gt: + // tests/artifacts/PrimitiveOps/contract.py:92-93 + // @arc4.abimethod() + // def verify_uint64_gt(self, a: UInt64, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:94 + // result = a > b + frame_dig -2 + frame_dig -1 + > + // tests/artifacts/PrimitiveOps/contract.py:95 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_ge(a: uint64, b: uint64) -> uint64: +verify_uint64_ge: + // tests/artifacts/PrimitiveOps/contract.py:97-98 + // @arc4.abimethod() + // def verify_uint64_ge(self, a: UInt64, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:99 + // result = a >= b + frame_dig -2 + frame_dig -1 + >= + // tests/artifacts/PrimitiveOps/contract.py:100 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_init(raw_value: uint64) -> bytes: +verify_bytes_init: + // tests/artifacts/PrimitiveOps/contract.py:102-103 + // @arc4.abimethod() + // def verify_bytes_init(self, raw_value: UInt64) -> Bytes: + proto 1 1 + // tests/artifacts/PrimitiveOps/contract.py:104 + // result = op.itob(raw_value) + frame_dig -1 + itob + // tests/artifacts/PrimitiveOps/contract.py:105 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_add(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64) -> bytes: +verify_bytes_add: + // tests/artifacts/PrimitiveOps/contract.py:107-110 + // @arc4.abimethod() + // def verify_bytes_add( + // self, a: Bytes, b: Bytes, pad_a_size: UInt64, pad_b_size: UInt64 + // ) -> Bytes: + proto 4 1 + // tests/artifacts/PrimitiveOps/contract.py:111 + // a = op.bzero(pad_a_size) + a + frame_dig -2 + bzero + frame_dig -4 + concat + frame_bury -4 + // tests/artifacts/PrimitiveOps/contract.py:112 + // b = op.bzero(pad_b_size) + b + frame_dig -1 + bzero + frame_dig -3 + concat + frame_bury -3 + // tests/artifacts/PrimitiveOps/contract.py:113 + // result = a + b + frame_dig -4 + frame_dig -3 + concat + // tests/artifacts/PrimitiveOps/contract.py:114 + // result = op.sha256(result) + sha256 + // tests/artifacts/PrimitiveOps/contract.py:115 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_eq(a: bytes, b: bytes) -> uint64: +verify_bytes_eq: + // tests/artifacts/PrimitiveOps/contract.py:117-118 + // @arc4.abimethod() + // def verify_bytes_eq(self, a: Bytes, b: Bytes) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:119 + // result = a == b + frame_dig -2 + frame_dig -1 + == + // tests/artifacts/PrimitiveOps/contract.py:120 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_ne(a: bytes, b: bytes) -> uint64: +verify_bytes_ne: + // tests/artifacts/PrimitiveOps/contract.py:122-123 + // @arc4.abimethod() + // def verify_bytes_ne(self, a: Bytes, b: Bytes) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:124 + // result = a != b + frame_dig -2 + frame_dig -1 + != + // tests/artifacts/PrimitiveOps/contract.py:125 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_and(a: bytes, b: bytes) -> bytes: +verify_bytes_and: + // tests/artifacts/PrimitiveOps/contract.py:127-128 + // @arc4.abimethod() + // def verify_bytes_and(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:129 + // result = a & b + frame_dig -2 + frame_dig -1 + b& + // tests/artifacts/PrimitiveOps/contract.py:130 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_or(a: bytes, b: bytes) -> bytes: +verify_bytes_or: + // tests/artifacts/PrimitiveOps/contract.py:132-133 + // @arc4.abimethod() + // def verify_bytes_or(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:134 + // result = a | b + frame_dig -2 + frame_dig -1 + b| + // tests/artifacts/PrimitiveOps/contract.py:135 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_xor(a: bytes, b: bytes) -> bytes: +verify_bytes_xor: + // tests/artifacts/PrimitiveOps/contract.py:137-138 + // @arc4.abimethod() + // def verify_bytes_xor(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:139 + // result = a ^ b + frame_dig -2 + frame_dig -1 + b^ + // tests/artifacts/PrimitiveOps/contract.py:140 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_not(a: bytes, pad_size: uint64) -> bytes: +verify_bytes_not: + // tests/artifacts/PrimitiveOps/contract.py:142-143 + // @arc4.abimethod() + // def verify_bytes_not(self, a: Bytes, pad_size: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:144 + // a = op.bzero(pad_size) + a + frame_dig -1 + bzero + frame_dig -2 + concat + dup + frame_bury -2 + // tests/artifacts/PrimitiveOps/contract.py:145 + // result = ~a + b~ + // tests/artifacts/PrimitiveOps/contract.py:146 + // result = op.sha256(result) + sha256 + // tests/artifacts/PrimitiveOps/contract.py:147 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_add(a: bytes, b: bytes) -> bytes: +verify_biguint_add: + // tests/artifacts/PrimitiveOps/contract.py:149-150 + // @arc4.abimethod() + // def verify_biguint_add(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:153 + // result = a_biguint + b_biguint + frame_dig -2 + frame_dig -1 + b+ + // tests/artifacts/PrimitiveOps/contract.py:154 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_add_uint64(a: bytes, b: uint64) -> bytes: +verify_biguint_add_uint64: + // tests/artifacts/PrimitiveOps/contract.py:156-157 + // @arc4.abimethod() + // def verify_biguint_add_uint64(self, a: Bytes, b: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:159 + // result = a_biguint + b + frame_dig -1 + itob + frame_dig -2 + b+ + // tests/artifacts/PrimitiveOps/contract.py:160 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_sub(a: bytes, b: bytes) -> bytes: +verify_biguint_sub: + // tests/artifacts/PrimitiveOps/contract.py:162-163 + // @arc4.abimethod() + // def verify_biguint_sub(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:166 + // result = a_biguint - b_biguint + frame_dig -2 + frame_dig -1 + b- + // tests/artifacts/PrimitiveOps/contract.py:167 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_sub_uint64(a: bytes, b: uint64) -> bytes: +verify_biguint_sub_uint64: + // tests/artifacts/PrimitiveOps/contract.py:169-170 + // @arc4.abimethod() + // def verify_biguint_sub_uint64(self, a: Bytes, b: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:172 + // result = a_biguint - b + frame_dig -1 + itob + frame_dig -2 + swap + b- + // tests/artifacts/PrimitiveOps/contract.py:173 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_mul(a: bytes, b: bytes) -> bytes: +verify_biguint_mul: + // tests/artifacts/PrimitiveOps/contract.py:175-176 + // @arc4.abimethod() + // def verify_biguint_mul(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:179 + // result = a_biguint * b_biguint + frame_dig -2 + frame_dig -1 + b* + // tests/artifacts/PrimitiveOps/contract.py:180 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_mul_uint64(a: bytes, b: uint64) -> bytes: +verify_biguint_mul_uint64: + // tests/artifacts/PrimitiveOps/contract.py:182-183 + // @arc4.abimethod() + // def verify_biguint_mul_uint64(self, a: Bytes, b: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:185 + // result = a_biguint * b + frame_dig -1 + itob + frame_dig -2 + b* + // tests/artifacts/PrimitiveOps/contract.py:186 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_div(a: bytes, b: bytes) -> bytes: +verify_biguint_div: + // tests/artifacts/PrimitiveOps/contract.py:188-189 + // @arc4.abimethod() + // def verify_biguint_div(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:192 + // result = a_biguint // b_biguint + frame_dig -2 + frame_dig -1 + b/ + // tests/artifacts/PrimitiveOps/contract.py:193 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_div_uint64(a: bytes, b: uint64) -> bytes: +verify_biguint_div_uint64: + // tests/artifacts/PrimitiveOps/contract.py:195-196 + // @arc4.abimethod() + // def verify_biguint_div_uint64(self, a: Bytes, b: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:198 + // result = a_biguint // b + frame_dig -1 + itob + frame_dig -2 + swap + b/ + // tests/artifacts/PrimitiveOps/contract.py:199 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_mod(a: bytes, b: bytes) -> bytes: +verify_biguint_mod: + // tests/artifacts/PrimitiveOps/contract.py:201-202 + // @arc4.abimethod() + // def verify_biguint_mod(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:205 + // result = a_biguint % b_biguint + frame_dig -2 + frame_dig -1 + b% + // tests/artifacts/PrimitiveOps/contract.py:206 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_mod_uint64(a: bytes, b: uint64) -> bytes: +verify_biguint_mod_uint64: + // tests/artifacts/PrimitiveOps/contract.py:208-209 + // @arc4.abimethod() + // def verify_biguint_mod_uint64(self, a: Bytes, b: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:211 + // result = a_biguint % b + frame_dig -1 + itob + frame_dig -2 + swap + b% + // tests/artifacts/PrimitiveOps/contract.py:212 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_and(a: bytes, b: bytes) -> bytes: +verify_biguint_and: + // tests/artifacts/PrimitiveOps/contract.py:214-215 + // @arc4.abimethod() + // def verify_biguint_and(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:218 + // result = a_biguint & b_biguint + frame_dig -2 + frame_dig -1 + b& + // tests/artifacts/PrimitiveOps/contract.py:219 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_and_uint64(a: bytes, b: uint64) -> bytes: +verify_biguint_and_uint64: + // tests/artifacts/PrimitiveOps/contract.py:221-222 + // @arc4.abimethod() + // def verify_biguint_and_uint64(self, a: Bytes, b: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:224 + // result = a_biguint & b + frame_dig -1 + itob + frame_dig -2 + b& + // tests/artifacts/PrimitiveOps/contract.py:225 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_or(a: bytes, b: bytes) -> bytes: +verify_biguint_or: + // tests/artifacts/PrimitiveOps/contract.py:227-228 + // @arc4.abimethod() + // def verify_biguint_or(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:231 + // result = a_biguint | b_biguint + frame_dig -2 + frame_dig -1 + b| + // tests/artifacts/PrimitiveOps/contract.py:232 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_or_uint64(a: bytes, b: uint64) -> bytes: +verify_biguint_or_uint64: + // tests/artifacts/PrimitiveOps/contract.py:234-235 + // @arc4.abimethod() + // def verify_biguint_or_uint64(self, a: Bytes, b: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:237 + // result = a_biguint | b + frame_dig -1 + itob + frame_dig -2 + b| + // tests/artifacts/PrimitiveOps/contract.py:238 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_xor(a: bytes, b: bytes) -> bytes: +verify_biguint_xor: + // tests/artifacts/PrimitiveOps/contract.py:240-241 + // @arc4.abimethod() + // def verify_biguint_xor(self, a: Bytes, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:244 + // result = a_biguint ^ b_biguint + frame_dig -2 + frame_dig -1 + b^ + // tests/artifacts/PrimitiveOps/contract.py:245 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_xor_uint64(a: bytes, b: uint64) -> bytes: +verify_biguint_xor_uint64: + // tests/artifacts/PrimitiveOps/contract.py:247-248 + // @arc4.abimethod() + // def verify_biguint_xor_uint64(self, a: Bytes, b: UInt64) -> Bytes: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:250 + // result = a_biguint ^ b + frame_dig -1 + itob + frame_dig -2 + b^ + // tests/artifacts/PrimitiveOps/contract.py:251 + // return result.bytes + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_eq(a: bytes, b: bytes) -> uint64: +verify_biguint_eq: + // tests/artifacts/PrimitiveOps/contract.py:253-254 + // @arc4.abimethod() + // def verify_biguint_eq(self, a: Bytes, b: Bytes) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:257 + // result = a_biguint == b_biguint + frame_dig -2 + frame_dig -1 + b== + // tests/artifacts/PrimitiveOps/contract.py:258 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_eq_uint64(a: bytes, b: uint64) -> uint64: +verify_biguint_eq_uint64: + // tests/artifacts/PrimitiveOps/contract.py:260-261 + // @arc4.abimethod() + // def verify_biguint_eq_uint64(self, a: Bytes, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:263 + // result = a_biguint == b + frame_dig -1 + itob + frame_dig -2 + b== + // tests/artifacts/PrimitiveOps/contract.py:264 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_ne(a: bytes, b: bytes) -> uint64: +verify_biguint_ne: + // tests/artifacts/PrimitiveOps/contract.py:266-267 + // @arc4.abimethod() + // def verify_biguint_ne(self, a: Bytes, b: Bytes) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:270 + // result = a_biguint != b_biguint + frame_dig -2 + frame_dig -1 + b!= + // tests/artifacts/PrimitiveOps/contract.py:271 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_ne_uint64(a: bytes, b: uint64) -> uint64: +verify_biguint_ne_uint64: + // tests/artifacts/PrimitiveOps/contract.py:273-274 + // @arc4.abimethod() + // def verify_biguint_ne_uint64(self, a: Bytes, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:276 + // result = a_biguint != b + frame_dig -1 + itob + frame_dig -2 + b!= + // tests/artifacts/PrimitiveOps/contract.py:277 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_lt(a: bytes, b: bytes) -> uint64: +verify_biguint_lt: + // tests/artifacts/PrimitiveOps/contract.py:279-280 + // @arc4.abimethod() + // def verify_biguint_lt(self, a: Bytes, b: Bytes) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:283 + // result = a_biguint < b_biguint + frame_dig -2 + frame_dig -1 + b< + // tests/artifacts/PrimitiveOps/contract.py:284 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_lt_uint64(a: bytes, b: uint64) -> uint64: +verify_biguint_lt_uint64: + // tests/artifacts/PrimitiveOps/contract.py:286-287 + // @arc4.abimethod() + // def verify_biguint_lt_uint64(self, a: Bytes, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:289 + // result = a_biguint < b + frame_dig -1 + itob + frame_dig -2 + b> + // tests/artifacts/PrimitiveOps/contract.py:290 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_le(a: bytes, b: bytes) -> uint64: +verify_biguint_le: + // tests/artifacts/PrimitiveOps/contract.py:292-293 + // @arc4.abimethod() + // def verify_biguint_le(self, a: Bytes, b: Bytes) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:296 + // result = a_biguint <= b_biguint + frame_dig -2 + frame_dig -1 + b<= + // tests/artifacts/PrimitiveOps/contract.py:297 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_le_uint64(a: bytes, b: uint64) -> uint64: +verify_biguint_le_uint64: + // tests/artifacts/PrimitiveOps/contract.py:299-300 + // @arc4.abimethod() + // def verify_biguint_le_uint64(self, a: Bytes, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:302 + // result = a_biguint <= b + frame_dig -1 + itob + frame_dig -2 + b>= + // tests/artifacts/PrimitiveOps/contract.py:303 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_gt(a: bytes, b: bytes) -> uint64: +verify_biguint_gt: + // tests/artifacts/PrimitiveOps/contract.py:305-306 + // @arc4.abimethod() + // def verify_biguint_gt(self, a: Bytes, b: Bytes) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:309 + // result = a_biguint > b_biguint + frame_dig -2 + frame_dig -1 + b> + // tests/artifacts/PrimitiveOps/contract.py:310 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_gt_uint64(a: bytes, b: uint64) -> uint64: +verify_biguint_gt_uint64: + // tests/artifacts/PrimitiveOps/contract.py:312-313 + // @arc4.abimethod() + // def verify_biguint_gt_uint64(self, a: Bytes, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:315 + // result = a_biguint > b + frame_dig -1 + itob + frame_dig -2 + b< + // tests/artifacts/PrimitiveOps/contract.py:316 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_ge(a: bytes, b: bytes) -> uint64: +verify_biguint_ge: + // tests/artifacts/PrimitiveOps/contract.py:318-319 + // @arc4.abimethod() + // def verify_biguint_ge(self, a: Bytes, b: Bytes) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:322 + // result = a_biguint >= b_biguint + frame_dig -2 + frame_dig -1 + b>= + // tests/artifacts/PrimitiveOps/contract.py:323 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_ge_uint64(a: bytes, b: uint64) -> uint64: +verify_biguint_ge_uint64: + // tests/artifacts/PrimitiveOps/contract.py:325-326 + // @arc4.abimethod() + // def verify_biguint_ge_uint64(self, a: Bytes, b: UInt64) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:328 + // result = a_biguint >= b + frame_dig -1 + itob + frame_dig -2 + b<= + // tests/artifacts/PrimitiveOps/contract.py:329 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_string_init(a: bytes) -> bytes: +verify_string_init: + // tests/artifacts/PrimitiveOps/contract.py:331-332 + // @arc4.abimethod + // def verify_string_init(self, a: String) -> String: + proto 1 1 + // tests/artifacts/PrimitiveOps/contract.py:333 + // result = String("Hello, ") + a + byte "Hello, " + frame_dig -1 + concat + // tests/artifacts/PrimitiveOps/contract.py:334 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_string_startswith(a: bytes, b: bytes) -> uint64: +verify_string_startswith: + // tests/artifacts/PrimitiveOps/contract.py:336-337 + // @arc4.abimethod + // def verify_string_startswith(self, a: String, b: String) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:338 + // result = a.startswith(b) + frame_dig -1 + len + dup + frame_dig -2 + len + > + bz verify_string_startswith_ternary_false@2 + int 0 + b verify_string_startswith_ternary_merge@3 + +verify_string_startswith_ternary_false@2: + // tests/artifacts/PrimitiveOps/contract.py:338 + // result = a.startswith(b) + frame_dig -2 + int 0 + frame_dig 0 + extract3 + frame_dig -1 + == + +verify_string_startswith_ternary_merge@3: + // tests/artifacts/PrimitiveOps/contract.py:339 + // return result + swap + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_string_endswith(a: bytes, b: bytes) -> uint64: +verify_string_endswith: + // tests/artifacts/PrimitiveOps/contract.py:341-342 + // @arc4.abimethod + // def verify_string_endswith(self, a: String, b: String) -> bool: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:343 + // result = a.endswith(b) + frame_dig -1 + len + dup + frame_dig -2 + len + dup + cover 2 + > + bz verify_string_endswith_ternary_false@2 + int 0 + b verify_string_endswith_ternary_merge@3 + +verify_string_endswith_ternary_false@2: + // tests/artifacts/PrimitiveOps/contract.py:343 + // result = a.endswith(b) + frame_dig 1 + frame_dig 0 + dup + cover 2 + - + frame_dig -2 + swap + uncover 2 + extract3 + frame_dig -1 + == + +verify_string_endswith_ternary_merge@3: + // tests/artifacts/PrimitiveOps/contract.py:344 + // return result + frame_bury 0 + retsub + + +// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_string_join(a: bytes, b: bytes) -> bytes: +verify_string_join: + // tests/artifacts/PrimitiveOps/contract.py:346-347 + // @arc4.abimethod + // def verify_string_join(self, a: String, b: String) -> String: + proto 2 1 + // tests/artifacts/PrimitiveOps/contract.py:348 + // result = String(", ").join((a, b)) + frame_dig -2 + byte ", " + concat + frame_dig -1 + concat + // tests/artifacts/PrimitiveOps/contract.py:349 + // return result + retsub + + +// tests.artifacts.PrimitiveOps.contract.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/PrimitiveOps/contract.py:351-367 + // @arc4.abimethod + // def verify_log( # noqa: PLR0913 + // self, + // a: String, + // b: UInt64, + // c: Bytes, + // d: Bytes, + // e: arc4.Bool, + // f: arc4.String, + // g: arc4.UIntN[typing.Literal[64]], + // h: arc4.BigUIntN[typing.Literal[256]], + // i: arc4.UFixedNxM[typing.Literal[32], typing.Literal[8]], + // j: arc4.BigUFixedNxM[typing.Literal[256], typing.Literal[16]], + // k: Bytes, + // m: Bytes, + // n: Bytes, + // ) -> None: + proto 13 0 + // tests/artifacts/PrimitiveOps/contract.py:372 + // log(a, b, c, d_biguint, e, f, g, h, i, j, arc4_k, arc4_m, arc4_n, sep="-") + frame_dig -13 + byte "-" + concat + frame_dig -12 + itob + concat + byte "-" + concat + frame_dig -11 + concat + byte "-" + concat + frame_dig -10 + concat + byte "-" + concat + frame_dig -9 + concat + byte "-" + concat + frame_dig -8 + concat + byte "-" + concat + frame_dig -7 + concat + byte "-" + concat + frame_dig -6 + concat + byte "-" + concat + frame_dig -5 + concat + byte "-" + concat + frame_dig -4 + concat + byte "-" + concat + frame_dig -3 + concat + byte "-" + concat + frame_dig -2 + concat + byte "-" + concat + frame_dig -1 + concat + log + retsub diff --git a/tests/artifacts/primitives/data/PrimitiveOpsContract.arc32.json b/tests/artifacts/primitives/data/PrimitiveOpsContract.arc32.json new file mode 100644 index 0000000..0a9d7e5 --- /dev/null +++ b/tests/artifacts/primitives/data/PrimitiveOpsContract.arc32.json @@ -0,0 +1,1393 @@ +{ + "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_string_init(string)string": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_string_startswith(string,string)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_string_endswith(string,string)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "verify_string_join(string,string)string": { + "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": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdANjQKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9pbml0KGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfYWRkKHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X3N1Yih1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9tdWwodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfZGl2KHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X21vZCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9hbmQodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfb3IodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfeG9yKHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X25vdCh1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2xzaGlmdCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9yc2hpZnQodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfcG93KHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2VxKHVpbnQ2NCx1aW50NjQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9uZSh1aW50NjQsdWludDY0KWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfbHQodWludDY0LHVpbnQ2NClib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2xlKHVpbnQ2NCx1aW50NjQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9ndCh1aW50NjQsdWludDY0KWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfZ2UodWludDY0LHVpbnQ2NClib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfaW5pdCh1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfYWRkKGJ5dGVbXSxieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9ieXRlc19lcShieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9ieXRlc19uZShieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9ieXRlc19hbmQoYnl0ZVtdLGJ5dGVbXSlieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9ieXRlc19vcihieXRlW10sYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2J5dGVzX3hvcihieXRlW10sYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2J5dGVzX25vdChieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfYWRkKGJ5dGVbXSxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9hZGRfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9zdWIoYnl0ZVtdLGJ5dGVbXSlieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X211bChieXRlW10sYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZGl2KGJ5dGVbXSxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9kaXZfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9tb2QoYnl0ZVtdLGJ5dGVbXSlieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X21vZF91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X2FuZChieXRlW10sYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfb3IoYnl0ZVtdLGJ5dGVbXSlieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfeG9yKGJ5dGVbXSxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF94b3JfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9lcShieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X25lKGJ5dGVbXSxieXRlW10pYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbHQoYnl0ZVtdLGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9sdF91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9sZShieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X2xlX3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X2d0KGJ5dGVbXSxieXRlW10pYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9nZV91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2luaXQoc3RyaW5nKXN0cmluZyIKICAgIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19zdGFydHN3aXRoKHN0cmluZyxzdHJpbmcpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19lbmRzd2l0aChzdHJpbmcsc3RyaW5nKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9zdHJpbmdfam9pbihzdHJpbmcsc3RyaW5nKXN0cmluZyIKICAgIG1ldGhvZCAidmVyaWZ5X2xvZyhzdHJpbmcsdWludDY0LGJ5dGVbXSxieXRlW10sYm9vbCxzdHJpbmcsdWludDY0LHVpbnQyNTYsdWZpeGVkMzJ4OCx1Zml4ZWQyNTZ4MTYsYnl0ZVtdLGJ5dGVbXSxieXRlW10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X3VpbnQ2NF9pbml0X3JvdXRlQDIgbWFpbl92ZXJpZnlfdWludDY0X2FkZF9yb3V0ZUAzIG1haW5fdmVyaWZ5X3VpbnQ2NF9zdWJfcm91dGVANCBtYWluX3ZlcmlmeV91aW50NjRfbXVsX3JvdXRlQDUgbWFpbl92ZXJpZnlfdWludDY0X2Rpdl9yb3V0ZUA2IG1haW5fdmVyaWZ5X3VpbnQ2NF9tb2Rfcm91dGVANyBtYWluX3ZlcmlmeV91aW50NjRfYW5kX3JvdXRlQDggbWFpbl92ZXJpZnlfdWludDY0X29yX3JvdXRlQDkgbWFpbl92ZXJpZnlfdWludDY0X3hvcl9yb3V0ZUAxMCBtYWluX3ZlcmlmeV91aW50NjRfbm90X3JvdXRlQDExIG1haW5fdmVyaWZ5X3VpbnQ2NF9sc2hpZnRfcm91dGVAMTIgbWFpbl92ZXJpZnlfdWludDY0X3JzaGlmdF9yb3V0ZUAxMyBtYWluX3ZlcmlmeV91aW50NjRfcG93X3JvdXRlQDE0IG1haW5fdmVyaWZ5X3VpbnQ2NF9lcV9yb3V0ZUAxNSBtYWluX3ZlcmlmeV91aW50NjRfbmVfcm91dGVAMTYgbWFpbl92ZXJpZnlfdWludDY0X2x0X3JvdXRlQDE3IG1haW5fdmVyaWZ5X3VpbnQ2NF9sZV9yb3V0ZUAxOCBtYWluX3ZlcmlmeV91aW50NjRfZ3Rfcm91dGVAMTkgbWFpbl92ZXJpZnlfdWludDY0X2dlX3JvdXRlQDIwIG1haW5fdmVyaWZ5X2J5dGVzX2luaXRfcm91dGVAMjEgbWFpbl92ZXJpZnlfYnl0ZXNfYWRkX3JvdXRlQDIyIG1haW5fdmVyaWZ5X2J5dGVzX2VxX3JvdXRlQDIzIG1haW5fdmVyaWZ5X2J5dGVzX25lX3JvdXRlQDI0IG1haW5fdmVyaWZ5X2J5dGVzX2FuZF9yb3V0ZUAyNSBtYWluX3ZlcmlmeV9ieXRlc19vcl9yb3V0ZUAyNiBtYWluX3ZlcmlmeV9ieXRlc194b3Jfcm91dGVAMjcgbWFpbl92ZXJpZnlfYnl0ZXNfbm90X3JvdXRlQDI4IG1haW5fdmVyaWZ5X2JpZ3VpbnRfYWRkX3JvdXRlQDI5IG1haW5fdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NF9yb3V0ZUAzMCBtYWluX3ZlcmlmeV9iaWd1aW50X3N1Yl9yb3V0ZUAzMSBtYWluX3ZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjRfcm91dGVAMzIgbWFpbl92ZXJpZnlfYmlndWludF9tdWxfcm91dGVAMzMgbWFpbl92ZXJpZnlfYmlndWludF9tdWxfdWludDY0X3JvdXRlQDM0IG1haW5fdmVyaWZ5X2JpZ3VpbnRfZGl2X3JvdXRlQDM1IG1haW5fdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NF9yb3V0ZUAzNiBtYWluX3ZlcmlmeV9iaWd1aW50X21vZF9yb3V0ZUAzNyBtYWluX3ZlcmlmeV9iaWd1aW50X21vZF91aW50NjRfcm91dGVAMzggbWFpbl92ZXJpZnlfYmlndWludF9hbmRfcm91dGVAMzkgbWFpbl92ZXJpZnlfYmlndWludF9hbmRfdWludDY0X3JvdXRlQDQwIG1haW5fdmVyaWZ5X2JpZ3VpbnRfb3Jfcm91dGVANDEgbWFpbl92ZXJpZnlfYmlndWludF9vcl91aW50NjRfcm91dGVANDIgbWFpbl92ZXJpZnlfYmlndWludF94b3Jfcm91dGVANDMgbWFpbl92ZXJpZnlfYmlndWludF94b3JfdWludDY0X3JvdXRlQDQ0IG1haW5fdmVyaWZ5X2JpZ3VpbnRfZXFfcm91dGVANDUgbWFpbl92ZXJpZnlfYmlndWludF9lcV91aW50NjRfcm91dGVANDYgbWFpbl92ZXJpZnlfYmlndWludF9uZV9yb3V0ZUA0NyBtYWluX3ZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NF9yb3V0ZUA0OCBtYWluX3ZlcmlmeV9iaWd1aW50X2x0X3JvdXRlQDQ5IG1haW5fdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0X3JvdXRlQDUwIG1haW5fdmVyaWZ5X2JpZ3VpbnRfbGVfcm91dGVANTEgbWFpbl92ZXJpZnlfYmlndWludF9sZV91aW50NjRfcm91dGVANTIgbWFpbl92ZXJpZnlfYmlndWludF9ndF9yb3V0ZUA1MyBtYWluX3ZlcmlmeV9iaWd1aW50X2d0X3VpbnQ2NF9yb3V0ZUA1NCBtYWluX3ZlcmlmeV9iaWd1aW50X2dlX3JvdXRlQDU1IG1haW5fdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0X3JvdXRlQDU2IG1haW5fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDU3IG1haW5fdmVyaWZ5X3N0cmluZ19zdGFydHN3aXRoX3JvdXRlQDU4IG1haW5fdmVyaWZ5X3N0cmluZ19lbmRzd2l0aF9yb3V0ZUA1OSBtYWluX3ZlcmlmeV9zdHJpbmdfam9pbl9yb3V0ZUA2MCBtYWluX3ZlcmlmeV9sb2dfcm91dGVANjEKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X3VpbnQ2NF9pbml0X3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2luaXQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9hZGRfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2FkZAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludDY0X3N1Yl9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfc3ViCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50NjRfbXVsX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9tdWwKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9kaXZfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2RpdgogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludDY0X21vZF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfbW9kCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50NjRfYW5kX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9hbmQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9vcl9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfb3IKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF94b3Jfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF94b3IKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9ub3Rfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9ub3QKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9sc2hpZnRfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9sc2hpZnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9yc2hpZnRfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9yc2hpZnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9wb3dfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9wb3cKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9lcV9yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2VxCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludDY0X25lX3JvdXRlQDE2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfbmUKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50NjRfbHRfcm91dGVAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9sdAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9sZV9yb3V0ZUAxODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2xlCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludDY0X2d0X3JvdXRlQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6OTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfZ3QKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50NjRfZ2Vfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9nZQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX2luaXRfcm91dGVAMjE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTAyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfaW5pdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX2FkZF9yb3V0ZUAyMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEwNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2FkZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX2VxX3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfZXEKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9ieXRlc19uZV9yb3V0ZUAyNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX25lCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZXNfYW5kX3JvdXRlQDI1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfYW5kCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZXNfb3Jfcm91dGVAMjY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19vcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX3hvcl9yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX3hvcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX25vdF9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfbm90CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9hZGRfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FkZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NF9yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9hZGRfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9zdWJfcm91dGVAMzE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X3N1YgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NF9yb3V0ZUAzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9zdWJfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9tdWxfcm91dGVAMzM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X211bAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NF9yb3V0ZUAzNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tdWxfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9kaXZfcm91dGVAMzU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2RpdgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NF9yb3V0ZUAzNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9kaXZfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9tb2Rfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X21vZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NF9yb3V0ZUAzODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjA4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjA4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tb2RfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9hbmRfcm91dGVAMzk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIxNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FuZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NF9yb3V0ZUA0MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9hbmRfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9vcl9yb3V0ZUA0MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfb3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NF9yb3V0ZUA0MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9vcl91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X3hvcl9yb3V0ZUA0MzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfeG9yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF94b3JfdWludDY0X3JvdXRlQDQ0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X2VxX3JvdXRlQDQ1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9lcQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0X3JvdXRlQDQ2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfbmVfcm91dGVANDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X25lCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9uZV91aW50NjRfcm91dGVANDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0CiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9sdF9yb3V0ZUA0OToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjc5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbHQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X2x0X3VpbnQ2NF9yb3V0ZUA1MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sdF91aW50NjQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X2xlX3JvdXRlQDUxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyOTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sZQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0X3JvdXRlQDUyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2xlX3VpbnQ2NAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfZ3Rfcm91dGVANTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2d0CiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9ndF91aW50NjRfcm91dGVANTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0CiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9nZV9yb3V0ZUA1NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMxOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfZ2UKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X2dlX3VpbnQ2NF9yb3V0ZUA1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9nZV91aW50NjQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zdHJpbmdfaW5pdF9yb3V0ZUA1NzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzMxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfaW5pdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3N0cmluZ19zdGFydHN3aXRoX3JvdXRlQDU4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMzNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3N0cmluZ19lbmRzd2l0aF9yb3V0ZUA1OToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB2ZXJpZnlfc3RyaW5nX2VuZHN3aXRoCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc3RyaW5nX2pvaW5fcm91dGVANjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19qb2luCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfbG9nX3JvdXRlQDYxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozNTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDExCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgdmVyaWZ5X2xvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdANjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2luaXQocmF3X3ZhbHVlOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjctOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2luaXQoc2VsZiwgcmF3X3ZhbHVlOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjkKICAgIC8vIHJlc3VsdCA9IG9wLmJ0b2kocmF3X3ZhbHVlKQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfYWRkKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfYWRkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMi0xMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2FkZChzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE0CiAgICAvLyByZXN1bHQgPSBhICsgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICsKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9zdWIoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9zdWI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE3LTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV91aW50NjRfc3ViKHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTkKICAgIC8vIHJlc3VsdCA9IGEgLSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgLQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X211bChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X211bDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjItMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3VpbnQ2NF9tdWwoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gcmVzdWx0ID0gYSAqIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfZGl2KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfZGl2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNy0yOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2RpdihzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI5CiAgICAvLyByZXN1bHQgPSBhIC8vIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbW9kKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbW9kOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMi0zMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X21vZChzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM0CiAgICAvLyByZXN1bHQgPSBhICUgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9hbmQoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9hbmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM3LTM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV91aW50NjRfYW5kKHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzkKICAgIC8vIHJlc3VsdCA9IGEgJiBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgJgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo0MAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X29yKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfb3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjQyLTQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV91aW50NjRfb3Ioc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo0NAogICAgLy8gcmVzdWx0ID0gYSB8IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICB8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjQ1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfeG9yKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfeG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo0Ny00OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X3hvcihzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyByZXN1bHQgPSBhIF4gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIF4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NTAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9ub3QoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbm90OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1Mi01MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X25vdChzZWxmLCBhOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1NAogICAgLy8gcmVzdWx0ID0gfmEKICAgIGZyYW1lX2RpZyAtMQogICAgfgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1NQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2xzaGlmdChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2xzaGlmdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NTctNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3VpbnQ2NF9sc2hpZnQoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1OQogICAgLy8gcmVzdWx0ID0gYSA8PCBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2hsCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfcnNoaWZ0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfcnNoaWZ0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2Mi02MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X3JzaGlmdChzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjY0CiAgICAvLyByZXN1bHQgPSBhID4+IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NjUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9wb3coYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9wb3c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjY3LTY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV91aW50NjRfcG93KHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NjkKICAgIC8vIHJlc3VsdCA9IGEqKmIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NzAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9lcShhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo3Mi03MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2VxKHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojc0CiAgICAvLyByZXN1bHQgPSBhID09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo3NQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X25lKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV91aW50NjRfbmUoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NzkKICAgIC8vIHJlc3VsdCA9IGEgIT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjgwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbHQoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9sdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6ODItODMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3VpbnQ2NF9sdChzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo4NAogICAgLy8gcmVzdWx0ID0gYSA8IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojg1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbGUoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6ODctODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3VpbnQ2NF9sZShzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo4OQogICAgLy8gcmVzdWx0ID0gYSA8PSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPD0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6OTAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9ndChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo5Mi05MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2d0KHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojk0CiAgICAvLyByZXN1bHQgPSBhID4gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6OTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9nZShhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo5Ny05OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2dlKHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojk5CiAgICAvLyByZXN1bHQgPSBhID49IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA+PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMDAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2luaXQocmF3X3ZhbHVlOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZXNfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTAyLTEwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnl0ZXNfaW5pdChzZWxmLCByYXdfdmFsdWU6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTA0CiAgICAvLyByZXN1bHQgPSBvcC5pdG9iKHJhd192YWx1ZSkKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMDUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2FkZChhOiBieXRlcywgYjogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCwgcGFkX2Jfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTA3LTExMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnl0ZXNfYWRkKAogICAgLy8gICAgIHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgcGFkX2Ffc2l6ZTogVUludDY0LCBwYWRfYl9zaXplOiBVSW50NjQKICAgIC8vICkgLT4gQnl0ZXM6CiAgICBwcm90byA0IDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTExCiAgICAvLyBhID0gb3AuYnplcm8ocGFkX2Ffc2l6ZSkgKyBhCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSAtNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMTIKICAgIC8vIGIgPSBvcC5iemVybyhwYWRfYl9zaXplKSArIGIKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IC0zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjExMwogICAgLy8gcmVzdWx0ID0gYSArIGIKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTE0CiAgICAvLyByZXN1bHQgPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjExNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZXNfZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlc19lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTE3LTExOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnl0ZXNfZXEoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjExOQogICAgLy8gcmVzdWx0ID0gYSA9PSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTIwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVzX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMjItMTIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9ieXRlc19uZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTI0CiAgICAvLyByZXN1bHQgPSBhICE9IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMjUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2FuZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZXNfYW5kOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMjctMTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9ieXRlc19hbmQoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMjkKICAgIC8vIHJlc3VsdCA9IGEgJiBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYiYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTMwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19vcihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZXNfb3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzMi0xMzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2J5dGVzX29yKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTM0CiAgICAvLyByZXN1bHQgPSBhIHwgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZXNfeG9yKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc194b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzNy0xMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2J5dGVzX3hvcihzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzOQogICAgLy8gcmVzdWx0ID0gYSBeIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiXgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNDAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX25vdChhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc19ub3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE0Mi0xNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2J5dGVzX25vdChzZWxmLCBhOiBCeXRlcywgcGFkX3NpemU6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTQ0CiAgICAvLyBhID0gb3AuYnplcm8ocGFkX3NpemUpICsgYQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIGR1cAogICAgZnJhbWVfYnVyeSAtMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNDUKICAgIC8vIHJlc3VsdCA9IH5hCiAgICBifgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNDYKICAgIC8vIHJlc3VsdCA9IG9wLnNoYTI1NihyZXN1bHQpCiAgICBzaGEyNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTQ3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9hZGQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE0OS0xNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfYWRkKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgKyBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiKwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNTQKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTU2LTE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9hZGRfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE1OQogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50ICsgYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGIrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE2MAogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9zdWIoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfc3ViOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNjItMTYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X3N1YihzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE2NgogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50IC0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYi0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTY3CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE2OS0xNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NChzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNzIKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCAtIGIKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgZnJhbWVfZGlnIC0yCiAgICBzd2FwCiAgICBiLQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNzMKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfbXVsKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X211bDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTc1LTE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9tdWwoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNzkKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCAqIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE4MAogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9tdWxfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tdWxfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxODItMTgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X211bF91aW50NjQoc2VsZiwgYTogQnl0ZXMsIGI6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTg1CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgKiBiCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYioKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTg2CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2RpdihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9kaXY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE4OC0xODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfZGl2KHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTkyCiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgLy8gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYi8KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTkzCiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE5NS0xOTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NChzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxOTgKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCAvLyBiCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgc3dhcAogICAgYi8KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTk5CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X21vZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tb2Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIwMS0yMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfbW9kKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjA1CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgJSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiJQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMDYKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjA4LTIwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9tb2RfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIxMQogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50ICUgYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGIlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIxMgogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9hbmQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfYW5kOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMTQtMjE1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X2FuZChzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIxOAogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50ICYgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYiYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjE5CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIyMS0yMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NChzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMjQKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCAmIGIKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgZnJhbWVfZGlnIC0yCiAgICBiJgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMjUKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfb3IoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfb3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIyNy0yMjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfb3Ioc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMzEKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCB8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIzMgogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9vcl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjM0LTIzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9vcl91aW50NjQoc2VsZiwgYTogQnl0ZXMsIGI6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjM3CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgfCBiCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjM4CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3hvcihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF94b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI0MC0yNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfeG9yKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjQ0CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgXiBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiXgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNDUKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfeG9yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfeG9yX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjQ3LTI0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF94b3JfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI1MAogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50IF4gYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI1MQogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI1My0yNTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfZXEoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI1NwogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50ID09IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGI9PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNTgKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNjAtMjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NChzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI2MwogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50ID09IGIKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgZnJhbWVfZGlnIC0yCiAgICBiPT0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjY0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjY2LTI2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9uZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjcwCiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgIT0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYiE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9uZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9uZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3My0yNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjc2CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgIT0gYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGIhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNzcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNzktMjgwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X2x0KHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyODMKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCA8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGI8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI4NAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sdF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI4Ni0yODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjg5CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPCBiCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYj4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjkwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjkyLTI5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9sZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjk2CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPD0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYjw9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI5NwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI5OS0zMDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzAyCiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPD0gYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGI+PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMDMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMDUtMzA2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X2d0KHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMDkKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCA+IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGI+CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMxMAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9ndF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9ndF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMxMi0zMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzE1CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPiBiCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYjwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzE2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzE4LTMxOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9nZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzIyCiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPj0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYj49CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMyMwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9nZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMyNS0zMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzI4CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPj0gYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGI8PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMjkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19pbml0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3N0cmluZ19pbml0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMzEtMzMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB2ZXJpZnlfc3RyaW5nX2luaXQoc2VsZiwgYTogU3RyaW5nKSAtPiBTdHJpbmc6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzMzCiAgICAvLyByZXN1bHQgPSBTdHJpbmcoIkhlbGxvLCAiKSArIGEKICAgIGJ5dGUgIkhlbGxvLCAiCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMzQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19zdGFydHN3aXRoKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfc3RyaW5nX3N0YXJ0c3dpdGg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMzNi0zMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aChzZWxmLCBhOiBTdHJpbmcsIGI6IFN0cmluZykgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMzgKICAgIC8vIHJlc3VsdCA9IGEuc3RhcnRzd2l0aChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGR1cAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgID4KICAgIGJ6IHZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aF90ZXJuYXJ5X2ZhbHNlQDIKICAgIGludCAwCiAgICBiIHZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aF90ZXJuYXJ5X21lcmdlQDMKCnZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aF90ZXJuYXJ5X2ZhbHNlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMzOAogICAgLy8gcmVzdWx0ID0gYS5zdGFydHN3aXRoKGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAwCiAgICBmcmFtZV9kaWcgMAogICAgZXh0cmFjdDMKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KCnZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aF90ZXJuYXJ5X21lcmdlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMzOQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgc3dhcAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2VuZHN3aXRoKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfc3RyaW5nX2VuZHN3aXRoOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozNDEtMzQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB2ZXJpZnlfc3RyaW5nX2VuZHN3aXRoKHNlbGYsIGE6IFN0cmluZywgYjogU3RyaW5nKSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM0MwogICAgLy8gcmVzdWx0ID0gYS5lbmRzd2l0aChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGR1cAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGR1cAogICAgY292ZXIgMgogICAgPgogICAgYnogdmVyaWZ5X3N0cmluZ19lbmRzd2l0aF90ZXJuYXJ5X2ZhbHNlQDIKICAgIGludCAwCiAgICBiIHZlcmlmeV9zdHJpbmdfZW5kc3dpdGhfdGVybmFyeV9tZXJnZUAzCgp2ZXJpZnlfc3RyaW5nX2VuZHN3aXRoX3Rlcm5hcnlfZmFsc2VAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQzCiAgICAvLyByZXN1bHQgPSBhLmVuZHN3aXRoKGIpCiAgICBmcmFtZV9kaWcgMQogICAgZnJhbWVfZGlnIDAKICAgIGR1cAogICAgY292ZXIgMgogICAgLQogICAgZnJhbWVfZGlnIC0yCiAgICBzd2FwCiAgICB1bmNvdmVyIDIKICAgIGV4dHJhY3QzCiAgICBmcmFtZV9kaWcgLTEKICAgID09Cgp2ZXJpZnlfc3RyaW5nX2VuZHN3aXRoX3Rlcm5hcnlfbWVyZ2VAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQ0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19qb2luKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfam9pbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQ2LTM0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgdmVyaWZ5X3N0cmluZ19qb2luKHNlbGYsIGE6IFN0cmluZywgYjogU3RyaW5nKSAtPiBTdHJpbmc6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQ4CiAgICAvLyByZXN1bHQgPSBTdHJpbmcoIiwgIikuam9pbigoYSwgYikpCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ5dGUgIiwgIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozNDkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2xvZyhhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMsIGU6IGJ5dGVzLCBmOiBieXRlcywgZzogYnl0ZXMsIGg6IGJ5dGVzLCBpOiBieXRlcywgajogYnl0ZXMsIGs6IGJ5dGVzLCBtOiBieXRlcywgbjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM1MS0zNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHZlcmlmeV9sb2coICAjIG5vcWE6IFBMUjA5MTMKICAgIC8vICAgICBzZWxmLAogICAgLy8gICAgIGE6IFN0cmluZywKICAgIC8vICAgICBiOiBVSW50NjQsCiAgICAvLyAgICAgYzogQnl0ZXMsCiAgICAvLyAgICAgZDogQnl0ZXMsCiAgICAvLyAgICAgZTogYXJjNC5Cb29sLAogICAgLy8gICAgIGY6IGFyYzQuU3RyaW5nLAogICAgLy8gICAgIGc6IGFyYzQuVUludE5bdHlwaW5nLkxpdGVyYWxbNjRdXSwKICAgIC8vICAgICBoOiBhcmM0LkJpZ1VJbnROW3R5cGluZy5MaXRlcmFsWzI1Nl1dLAogICAgLy8gICAgIGk6IGFyYzQuVUZpeGVkTnhNW3R5cGluZy5MaXRlcmFsWzMyXSwgdHlwaW5nLkxpdGVyYWxbOF1dLAogICAgLy8gICAgIGo6IGFyYzQuQmlnVUZpeGVkTnhNW3R5cGluZy5MaXRlcmFsWzI1Nl0sIHR5cGluZy5MaXRlcmFsWzE2XV0sCiAgICAvLyAgICAgazogQnl0ZXMsCiAgICAvLyAgICAgbTogQnl0ZXMsCiAgICAvLyAgICAgbjogQnl0ZXMsCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byAxMyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM3MgogICAgLy8gbG9nKGEsIGIsIGMsIGRfYmlndWludCwgZSwgZiwgZywgaCwgaSwgaiwgYXJjNF9rLCBhcmM0X20sIGFyYzRfbiwgc2VwPSItIikKICAgIGZyYW1lX2RpZyAtMTMKICAgIGJ5dGUgIi0iCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMTIKICAgIGl0b2IKICAgIGNvbmNhdAogICAgYnl0ZSAiLSIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xMQogICAgY29uY2F0CiAgICBieXRlICItIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEwCiAgICBjb25jYXQKICAgIGJ5dGUgIi0iCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtOQogICAgY29uY2F0CiAgICBieXRlICItIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTgKICAgIGNvbmNhdAogICAgYnl0ZSAiLSIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC03CiAgICBjb25jYXQKICAgIGJ5dGUgIi0iCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtNgogICAgY29uY2F0CiAgICBieXRlICItIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTUKICAgIGNvbmNhdAogICAgYnl0ZSAiLSIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC00CiAgICBjb25jYXQKICAgIGJ5dGUgIi0iCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICBieXRlICItIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgYnl0ZSAiLSIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGxvZwogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + }, + "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_string_init", + "args": [ + { + "type": "string", + "name": "a" + } + ], + "readonly": false, + "returns": { + "type": "string" + } + }, + { + "name": "verify_string_startswith", + "args": [ + { + "type": "string", + "name": "a" + }, + { + "type": "string", + "name": "b" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } + }, + { + "name": "verify_string_endswith", + "args": [ + { + "type": "string", + "name": "a" + }, + { + "type": "string", + "name": "b" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } + }, + { + "name": "verify_string_join", + "args": [ + { + "type": "string", + "name": "a" + }, + { + "type": "string", + "name": "b" + } + ], + "readonly": false, + "returns": { + "type": "string" + } + }, + { + "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/primitives/data/PrimitiveOpsContract.clear.teal b/tests/artifacts/primitives/data/PrimitiveOpsContract.clear.teal new file mode 100644 index 0000000..8341d36 --- /dev/null +++ b/tests/artifacts/primitives/data/PrimitiveOpsContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.clear_state_program: + // tests/artifacts/PrimitiveOps/contract.py:6 + // class PrimitiveOpsContract(ARC4Contract): + int 1 + return diff --git a/tests/artifacts/state-ops/contract.algo.ts b/tests/artifacts/state-ops/contract.algo.ts new file mode 100644 index 0000000..2d52f85 --- /dev/null +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -0,0 +1,337 @@ +import { Account, Application, arc4, assert, Asset, bytes, op, Txn, uint64 } from '@algorandfoundation/algo-ts' + +function get_1st_ref_index(): uint64 { + return op.btoi(Txn.applicationArgs(1)) +} + +export class StateAcctParamsGetContract extends arc4.Contract { + @arc4.abimethod() + public verify_acct_balance(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctBalance(a) + const [value_index, funded_index] = op.AcctParams.acctBalance(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + assert(value == a.balance, 'expected Account balance to match') + assert(value == op.balance(a), 'expected op.balance to match') + assert(value == op.balance(get_1st_ref_index()), 'expected op.balance by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_min_balance(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctMinBalance(a) + const [value_index, funded_index] = op.AcctParams.acctMinBalance(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + assert(value == a.minBalance, 'expected Account min_balance to match') + assert(value == op.minBalance(a), 'expected op.min_balance to match') + assert(value == op.minBalance(get_1st_ref_index()), 'expected op.min_balance by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_auth_addr(a: Account): Account { + const [value, funded] = op.AcctParams.acctAuthAddr(a) + const [value_index, funded_index] = op.AcctParams.acctAuthAddr(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + // TODO: return arc4.Address(value) + return value + } + + @arc4.abimethod() + public verify_acct_total_num_uint(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalNumUint(a) + const [value_index, funded_index] = op.AcctParams.acctTotalNumUint(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_num_byte_slice(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalNumByteSlice(a) + const [value_index, funded_index] = op.AcctParams.acctTotalNumByteSlice(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_extra_app_pages(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalExtraAppPages(a) + const [value_index, funded_index] = op.AcctParams.acctTotalExtraAppPages(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_apps_created(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalAppsCreated(a) + const [value_index, funded_index] = op.AcctParams.acctTotalAppsCreated(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_apps_opted_in(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalAppsOptedIn(a) + const [value_index, funded_index] = op.AcctParams.acctTotalAppsOptedIn(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_assets_created(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalAssetsCreated(a) + const [value_index, funded_index] = op.AcctParams.acctTotalAssetsCreated(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_assets(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalAssets(a) + const [value_index, funded_index] = op.AcctParams.acctTotalAssets(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_boxes(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalBoxes(a) + const [value_index, funded_index] = op.AcctParams.acctTotalBoxes(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(funded == funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_box_bytes(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalBoxBytes(a) + const [value_index, funded_index] = op.AcctParams.acctTotalBoxBytes(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 { + @arc4.abimethod() + public verify_asset_holding_get(a: Account, b: Asset): uint64 { + const [balance, _val] = op.AssetHolding.assetBalance(a, b) + return balance + } + + @arc4.abimethod() + public verify_asset_frozen_get(a: Account, b: Asset): boolean { + const [frozen, _val] = op.AssetHolding.assetFrozen(a, b) + return frozen + } +} + +export class StateAssetParamsContract extends arc4.Contract { + @arc4.abimethod() + public verify_asset_params_get_total(a: Asset): uint64 { + const [value, exists] = op.AssetParams.assetTotal(a) + const [value_index, exists_index] = op.AssetParams.assetTotal(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_asset_params_get_decimals(a: Asset): uint64 { + const [value, exists] = op.AssetParams.assetDecimals(a) + const [value_index, exists_index] = op.AssetParams.assetDecimals(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_asset_params_get_default_frozen(a: Asset): boolean { + const [value, exists] = op.AssetParams.assetDefaultFrozen(a) + const [value_index, exists_index] = op.AssetParams.assetDefaultFrozen(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_asset_params_get_unit_name(a: Asset): bytes { + const [value, exists] = op.AssetParams.assetUnitName(a) + const [value_index, exists_index] = op.AssetParams.assetUnitName(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_asset_params_get_name(a: Asset): bytes { + const [value, exists] = op.AssetParams.assetName(a) + const [value_index, exists_index] = op.AssetParams.assetName(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_asset_params_get_url(a: Asset): bytes { + const [value, exists] = op.AssetParams.assetUrl(a) + const [value_index, exists_index] = op.AssetParams.assetUrl(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_asset_params_get_metadata_hash(a: Asset): bytes { + const [value, exists] = op.AssetParams.assetMetadataHash(a) + const [value_index, exists_index] = op.AssetParams.assetMetadataHash(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_asset_params_get_manager(a: Asset): Account { + const [value, exists] = op.AssetParams.assetManager(a) + const [value_index, exists_index] = op.AssetParams.assetManager(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + // TODO: return arc4.Address(value) + return value + } + + @arc4.abimethod() + public verify_asset_params_get_reserve(a: Asset): Account { + const [value, exists] = op.AssetParams.assetReserve(a) + const [value_index, exists_index] = op.AssetParams.assetReserve(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + // TODO: return arc4.Address(value) + return value + } + + @arc4.abimethod() + public verify_asset_params_get_freeze(a: Asset): Account { + const [value, exists] = op.AssetParams.assetFreeze(a) + const [value_index, exists_index] = op.AssetParams.assetFreeze(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + // TODO: return arc4.Address(value) + return value + } + + @arc4.abimethod() + public verify_asset_params_get_clawback(a: Asset): Account { + const [value, exists] = op.AssetParams.assetClawback(a) + const [value_index, exists_index] = op.AssetParams.assetClawback(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + // TODO: return arc4.Address(value) + return value + } + + @arc4.abimethod() + public verify_asset_params_get_creator(a: Asset): Account { + const [value, exists] = op.AssetParams.assetCreator(a) + const [value_index, exists_index] = op.AssetParams.assetCreator(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + // TODO: return arc4.Address(value) + return value + } +} + +export class StateAppParamsContract extends arc4.Contract { + @arc4.abimethod() + public verify_app_params_get_approval_program(a: Application): bytes { + const [value, exists] = op.AppParams.appApprovalProgram(a) + const [value_index, exists_index] = op.AppParams.appApprovalProgram(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_app_params_get_clear_state_program(a: Application): bytes { + const [value, exists] = op.AppParams.appClearStateProgram(a) + const [value_index, exists_index] = op.AppParams.appClearStateProgram(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_app_params_get_global_num_uint(a: Application): uint64 { + const [value, exists] = op.AppParams.appGlobalNumUint(a) + const [value_index, exists_index] = op.AppParams.appGlobalNumUint(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_app_params_get_global_num_byte_slice(a: Application): uint64 { + const [value, exists] = op.AppParams.appGlobalNumByteSlice(a) + const [value_index, exists_index] = op.AppParams.appGlobalNumByteSlice(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_app_params_get_local_num_uint(a: Application): uint64 { + const [value, exists] = op.AppParams.appLocalNumUint(a) + const [value_index, exists_index] = op.AppParams.appLocalNumUint(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_app_params_get_local_num_byte_slice(a: Application): uint64 { + const [value, exists] = op.AppParams.appLocalNumByteSlice(a) + const [value_index, exists_index] = op.AppParams.appLocalNumByteSlice(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_app_params_get_extra_program_pages(a: Application): uint64 { + const [value, exists] = op.AppParams.appExtraProgramPages(a) + const [value_index, exists_index] = op.AppParams.appExtraProgramPages(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + return value + } + + @arc4.abimethod() + public verify_app_params_get_creator(a: Application): Account { + const [value, exists] = op.AppParams.appCreator(a) + const [value_index, exists_index] = op.AppParams.appCreator(get_1st_ref_index()) + assert(value == value_index, 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + // TODO: return arc4.Address(value) + return value + } + + @arc4.abimethod() + public verify_app_params_get_address(a: Application): Account { + const [value, exists] = op.AppParams.appAddress(a) + const [value_index, exists_index] = op.AppParams.appAddress(get_1st_ref_index()) + // TODO: recompile when puya ts is ready + assert(value.bytes.toString() == value_index.bytes.toString(), 'expected value by index to match') + assert(exists == exists_index, 'expected exists by index to match') + // TODO: return arc4.Address(value) + return value + } +} diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal new file mode 100644 index 0000000..0b5e66e --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal @@ -0,0 +1,770 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAcctParamsGetContract.approval_program: + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@16 + method "verify_acct_balance(account)uint64" + method "verify_acct_min_balance(account)uint64" + method "verify_acct_auth_addr(account)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 main_verify_acct_balance_route@2 main_verify_acct_min_balance_route@3 main_verify_acct_auth_addr_route@4 main_verify_acct_total_num_uint_route@5 main_verify_acct_total_num_byte_slice_route@6 main_verify_acct_total_extra_app_pages_route@7 main_verify_acct_total_apps_created_route@8 main_verify_acct_total_apps_opted_in_route@9 main_verify_acct_total_assets_created_route@10 main_verify_acct_total_assets_route@11 main_verify_acct_total_boxes_route@12 main_verify_acct_total_box_bytes_route@13 + err // reject transaction + +main_verify_acct_balance_route@2: + // tests/artifacts/StateOps/contract.py:25 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:25 + // @arc4.abimethod() + callsub verify_acct_balance + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_min_balance_route@3: + // tests/artifacts/StateOps/contract.py:38 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:38 + // @arc4.abimethod() + callsub verify_acct_min_balance + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_auth_addr_route@4: + // tests/artifacts/StateOps/contract.py:51 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:51 + // @arc4.abimethod() + callsub verify_acct_auth_addr + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_total_num_uint_route@5: + // tests/artifacts/StateOps/contract.py:59 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:59 + // @arc4.abimethod() + callsub verify_acct_total_num_uint + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_total_num_byte_slice_route@6: + // tests/artifacts/StateOps/contract.py:67 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:67 + // @arc4.abimethod() + callsub verify_acct_total_num_byte_slice + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_total_extra_app_pages_route@7: + // tests/artifacts/StateOps/contract.py:77 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:77 + // @arc4.abimethod() + callsub verify_acct_total_extra_app_pages + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_total_apps_created_route@8: + // tests/artifacts/StateOps/contract.py:87 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:87 + // @arc4.abimethod() + callsub verify_acct_total_apps_created + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_total_apps_opted_in_route@9: + // tests/artifacts/StateOps/contract.py:95 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:95 + // @arc4.abimethod() + callsub verify_acct_total_apps_opted_in + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_total_assets_created_route@10: + // tests/artifacts/StateOps/contract.py:103 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:103 + // @arc4.abimethod() + callsub verify_acct_total_assets_created + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_total_assets_route@11: + // tests/artifacts/StateOps/contract.py:113 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:113 + // @arc4.abimethod() + callsub verify_acct_total_assets + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_total_boxes_route@12: + // tests/artifacts/StateOps/contract.py:121 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:121 + // @arc4.abimethod() + callsub verify_acct_total_boxes + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_acct_total_box_bytes_route@13: + // tests/artifacts/StateOps/contract.py:129 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/StateOps/contract.py:129 + // @arc4.abimethod() + callsub verify_acct_total_box_bytes + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@16: + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_balance(a: bytes) -> uint64: +verify_acct_balance: + // tests/artifacts/StateOps/contract.py:25-26 + // @arc4.abimethod() + // def verify_acct_balance(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:27 + // value, funded = op.AcctParamsGet.acct_balance(a) + frame_dig -1 + acct_params_get AcctBalance + swap + // tests/artifacts/StateOps/contract.py:28 + // value_index, funded_index = op.AcctParamsGet.acct_balance(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctBalance + cover 2 + // tests/artifacts/StateOps/contract.py:29 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:30 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:31 + // 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/StateOps/contract.py:32 + // assert value == algopy.op.balance(a), "expected op.balance to match" + frame_dig -1 + balance + dig 1 + == + assert // expected op.balance to match + // tests/artifacts/StateOps/contract.py:34 + // _get_1st_ref_index() + callsub _get_1st_ref_index + // tests/artifacts/StateOps/contract.py:33-35 + // assert value == algopy.op.balance( + // _get_1st_ref_index() + // ), "expected op.balance by index to match" + balance + dig 1 + == + assert // expected op.balance by index to match + // tests/artifacts/StateOps/contract.py:36 + // return value + retsub + + +// tests.artifacts.StateOps.contract._get_1st_ref_index() -> uint64: +_get_1st_ref_index: + // tests/artifacts/StateOps/contract.py:19-20 + // @subroutine + // def _get_1st_ref_index() -> UInt64: + proto 0 1 + // tests/artifacts/StateOps/contract.py:21 + // return op.btoi(Txn.application_args(1)) + txna ApplicationArgs 1 + btoi + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_min_balance(a: bytes) -> uint64: +verify_acct_min_balance: + // tests/artifacts/StateOps/contract.py:38-39 + // @arc4.abimethod() + // def verify_acct_min_balance(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:40 + // value, funded = op.AcctParamsGet.acct_min_balance(a) + frame_dig -1 + acct_params_get AcctMinBalance + swap + // tests/artifacts/StateOps/contract.py:41 + // value_index, funded_index = op.AcctParamsGet.acct_min_balance(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctMinBalance + cover 2 + // tests/artifacts/StateOps/contract.py:42 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:43 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:44 + // assert value == a.min_balance, "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/StateOps/contract.py:45 + // assert value == algopy.op.min_balance(a), "expected op.min_balance to match" + frame_dig -1 + min_balance + dig 1 + == + assert // expected op.min_balance to match + // tests/artifacts/StateOps/contract.py:47 + // _get_1st_ref_index() + callsub _get_1st_ref_index + // tests/artifacts/StateOps/contract.py:46-48 + // assert value == algopy.op.min_balance( + // _get_1st_ref_index() + // ), "expected op.min_balance by index to match" + min_balance + dig 1 + == + assert // expected op.min_balance by index to match + // tests/artifacts/StateOps/contract.py:49 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_auth_addr(a: bytes) -> bytes: +verify_acct_auth_addr: + // tests/artifacts/StateOps/contract.py:51-52 + // @arc4.abimethod() + // def verify_acct_auth_addr(self, a: algopy.Account) -> arc4.Address: + proto 1 1 + // tests/artifacts/StateOps/contract.py:53 + // value, funded = op.AcctParamsGet.acct_auth_addr(a) + frame_dig -1 + acct_params_get AcctAuthAddr + swap + // tests/artifacts/StateOps/contract.py:54 + // value_index, funded_index = op.AcctParamsGet.acct_auth_addr(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctAuthAddr + cover 2 + // tests/artifacts/StateOps/contract.py:55 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:56 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:57 + // return arc4.Address(value) + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_num_uint(a: bytes) -> uint64: +verify_acct_total_num_uint: + // tests/artifacts/StateOps/contract.py:59-60 + // @arc4.abimethod() + // def verify_acct_total_num_uint(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:61 + // value, funded = op.AcctParamsGet.acct_total_num_uint(a) + frame_dig -1 + acct_params_get AcctTotalNumUint + swap + // tests/artifacts/StateOps/contract.py:62 + // value_index, funded_index = op.AcctParamsGet.acct_total_num_uint(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalNumUint + cover 2 + // tests/artifacts/StateOps/contract.py:63 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:64 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:65 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_num_byte_slice(a: bytes) -> uint64: +verify_acct_total_num_byte_slice: + // tests/artifacts/StateOps/contract.py:67-68 + // @arc4.abimethod() + // def verify_acct_total_num_byte_slice(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:69 + // value, funded = op.AcctParamsGet.acct_total_num_byte_slice(a) + frame_dig -1 + acct_params_get AcctTotalNumByteSlice + swap + // tests/artifacts/StateOps/contract.py:71 + // _get_1st_ref_index() + callsub _get_1st_ref_index + // tests/artifacts/StateOps/contract.py:70-72 + // value_index, funded_index = op.AcctParamsGet.acct_total_num_byte_slice( + // _get_1st_ref_index() + // ) + acct_params_get AcctTotalNumByteSlice + cover 2 + // tests/artifacts/StateOps/contract.py:73 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:74 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:75 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_extra_app_pages(a: bytes) -> uint64: +verify_acct_total_extra_app_pages: + // tests/artifacts/StateOps/contract.py:77-78 + // @arc4.abimethod() + // def verify_acct_total_extra_app_pages(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:79 + // value, funded = op.AcctParamsGet.acct_total_extra_app_pages(a) + frame_dig -1 + acct_params_get AcctTotalExtraAppPages + swap + // tests/artifacts/StateOps/contract.py:81 + // _get_1st_ref_index() + callsub _get_1st_ref_index + // tests/artifacts/StateOps/contract.py:80-82 + // value_index, funded_index = op.AcctParamsGet.acct_total_extra_app_pages( + // _get_1st_ref_index() + // ) + acct_params_get AcctTotalExtraAppPages + cover 2 + // tests/artifacts/StateOps/contract.py:83 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:84 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:85 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_apps_created(a: bytes) -> uint64: +verify_acct_total_apps_created: + // tests/artifacts/StateOps/contract.py:87-88 + // @arc4.abimethod() + // def verify_acct_total_apps_created(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:89 + // value, funded = op.AcctParamsGet.acct_total_apps_created(a) + frame_dig -1 + acct_params_get AcctTotalAppsCreated + swap + // tests/artifacts/StateOps/contract.py:90 + // value_index, funded_index = op.AcctParamsGet.acct_total_apps_created(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalAppsCreated + cover 2 + // tests/artifacts/StateOps/contract.py:91 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:92 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:93 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_apps_opted_in(a: bytes) -> uint64: +verify_acct_total_apps_opted_in: + // tests/artifacts/StateOps/contract.py:95-96 + // @arc4.abimethod() + // def verify_acct_total_apps_opted_in(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:97 + // value, funded = op.AcctParamsGet.acct_total_apps_opted_in(a) + frame_dig -1 + acct_params_get AcctTotalAppsOptedIn + swap + // tests/artifacts/StateOps/contract.py:98 + // value_index, funded_index = op.AcctParamsGet.acct_total_apps_opted_in(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalAppsOptedIn + cover 2 + // tests/artifacts/StateOps/contract.py:99 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:100 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:101 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_assets_created(a: bytes) -> uint64: +verify_acct_total_assets_created: + // tests/artifacts/StateOps/contract.py:103-104 + // @arc4.abimethod() + // def verify_acct_total_assets_created(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:105 + // value, funded = op.AcctParamsGet.acct_total_assets_created(a) + frame_dig -1 + acct_params_get AcctTotalAssetsCreated + swap + // tests/artifacts/StateOps/contract.py:107 + // _get_1st_ref_index() + callsub _get_1st_ref_index + // tests/artifacts/StateOps/contract.py:106-108 + // value_index, funded_index = op.AcctParamsGet.acct_total_assets_created( + // _get_1st_ref_index() + // ) + acct_params_get AcctTotalAssetsCreated + cover 2 + // tests/artifacts/StateOps/contract.py:109 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:110 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:111 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_assets(a: bytes) -> uint64: +verify_acct_total_assets: + // tests/artifacts/StateOps/contract.py:113-114 + // @arc4.abimethod() + // def verify_acct_total_assets(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:115 + // value, funded = op.AcctParamsGet.acct_total_assets(a) + frame_dig -1 + acct_params_get AcctTotalAssets + swap + // tests/artifacts/StateOps/contract.py:116 + // value_index, funded_index = op.AcctParamsGet.acct_total_assets(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalAssets + cover 2 + // tests/artifacts/StateOps/contract.py:117 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:118 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:119 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_boxes(a: bytes) -> uint64: +verify_acct_total_boxes: + // tests/artifacts/StateOps/contract.py:121-122 + // @arc4.abimethod() + // def verify_acct_total_boxes(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:123 + // value, funded = op.AcctParamsGet.acct_total_boxes(a) + frame_dig -1 + acct_params_get AcctTotalBoxes + swap + // tests/artifacts/StateOps/contract.py:124 + // value_index, funded_index = op.AcctParamsGet.acct_total_boxes(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalBoxes + cover 2 + // tests/artifacts/StateOps/contract.py:125 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:126 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:127 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_box_bytes(a: bytes) -> uint64: +verify_acct_total_box_bytes: + // tests/artifacts/StateOps/contract.py:129-130 + // @arc4.abimethod() + // def verify_acct_total_box_bytes(self, a: algopy.Account) -> algopy.UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:131 + // value, funded = op.AcctParamsGet.acct_total_box_bytes(a) + frame_dig -1 + acct_params_get AcctTotalBoxBytes + swap + // tests/artifacts/StateOps/contract.py:132 + // value_index, funded_index = op.AcctParamsGet.acct_total_box_bytes(_get_1st_ref_index()) + callsub _get_1st_ref_index + acct_params_get AcctTotalBoxBytes + cover 2 + // tests/artifacts/StateOps/contract.py:133 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:134 + // assert funded == funded_index, "expected funded by index to match" + cover 2 + == + assert // expected funded by index to match + // tests/artifacts/StateOps/contract.py:135 + // return value + retsub diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json new file mode 100644 index 0000000..16b66ef --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json @@ -0,0 +1,253 @@ +{ + "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": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxNgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF9iYWxhbmNlKGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZShhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfYXV0aF9hZGRyKGFjY291bnQpYWRkcmVzcyIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlKGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cyhhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlcyhhY2NvdW50KXVpbnQ2NCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2FjY3RfYmFsYW5jZV9yb3V0ZUAyIG1haW5fdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Vfcm91dGVAMyBtYWluX3ZlcmlmeV9hY2N0X2F1dGhfYWRkcl9yb3V0ZUA0IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnRfcm91dGVANSBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDYgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXNfcm91dGVANyBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZF9yb3V0ZUA4IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbl9yb3V0ZUA5IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWRfcm91dGVAMTAgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfcm91dGVAMTEgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMiBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlc19yb3V0ZUAxMwogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9iYWxhbmNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X21pbl9iYWxhbmNlX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZQogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF9hdXRoX2FkZHJfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2F1dGhfYWRkcgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlc19yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZF9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW5fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4KICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2JveGVzX3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcwogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXNfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlcwogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfYmFsYW5jZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNS0yNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF9iYWxhbmNlKHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhbGdvcHkuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjcKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfYmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOAogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF9iYWxhbmNlKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzAKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMQogICAgLy8gYXNzZXJ0IHZhbHVlID09IGEuYmFsYW5jZSwgImV4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaCIKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMyCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gYWxnb3B5Lm9wLmJhbGFuY2UoYSksICJleHBlY3RlZCBvcC5iYWxhbmNlIHRvIG1hdGNoIgogICAgZnJhbWVfZGlnIC0xCiAgICBiYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5iYWxhbmNlIHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQKICAgIC8vIF9nZXRfMXN0X3JlZl9pbmRleCgpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzLTM1CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gYWxnb3B5Lm9wLmJhbGFuY2UoCiAgICAvLyAgICAgX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIC8vICksICJleHBlY3RlZCBvcC5iYWxhbmNlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AuYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5fZ2V0XzFzdF9yZWZfaW5kZXgoKSAtPiB1aW50NjQ6Cl9nZXRfMXN0X3JlZl9pbmRleDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOS0yMAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBfZ2V0XzFzdF9yZWZfaW5kZXgoKSAtPiBVSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMQogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uX2FyZ3MoMSkpCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgtMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Uoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MAogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF9taW5fYmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MQogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF9taW5fYmFsYW5jZShfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MgogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQzCiAgICAvLyBhc3NlcnQgZnVuZGVkID09IGZ1bmRlZF9pbmRleCwgImV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSBhLm1pbl9iYWxhbmNlLCAiZXhwZWN0ZWQgQWNjb3VudCBtaW5fYmFsYW5jZSB0byBtYXRjaCIKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIEFjY291bnQgbWluX2JhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NQogICAgLy8gYXNzZXJ0IHZhbHVlID09IGFsZ29weS5vcC5taW5fYmFsYW5jZShhKSwgImV4cGVjdGVkIG9wLm1pbl9iYWxhbmNlIHRvIG1hdGNoIgogICAgZnJhbWVfZGlnIC0xCiAgICBtaW5fYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AubWluX2JhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NwogICAgLy8gX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYtNDgKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSBhbGdvcHkub3AubWluX2JhbGFuY2UoCiAgICAvLyAgICAgX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIC8vICksICJleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCIKICAgIG1pbl9iYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYWNjdF9hdXRoX2FkZHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTEtNTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfYXV0aF9hZGRyKHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhcmM0LkFkZHJlc3M6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MwogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF9hdXRoX2FkZHIoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RBdXRoQWRkcgogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0CiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X2F1dGhfYWRkcihfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEF1dGhBZGRyCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTUKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NgogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3CiAgICAvLyByZXR1cm4gYXJjNC5BZGRyZXNzKHZhbHVlKQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5LTYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhbGdvcHkuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjEKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfbnVtX3VpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MgogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9udW1fdWludChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtVWludAogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYzCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjQKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjctNjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Uoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2OQogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzEKICAgIC8vIF9nZXRfMXN0X3JlZl9pbmRleCgpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcwLTcyCiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlKAogICAgLy8gICAgIF9nZXRfMXN0X3JlZl9pbmRleCgpCiAgICAvLyApCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3NAogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcyhzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsRXh0cmFBcHBQYWdlcwogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjgxCiAgICAvLyBfZ2V0XzFzdF9yZWZfaW5kZXgoKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4MC04MgogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoCiAgICAvLyAgICAgX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIC8vICkKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxFeHRyYUFwcFBhZ2VzCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6ODMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4NAogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg3LTg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg5CiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc0NyZWF0ZWQKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MAogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFwcHNDcmVhdGVkCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTEKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MgogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkzCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTUtOTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojk3CiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFwcHNPcHRlZEluCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTgKICAgIC8vIHZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXggPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYXBwc19vcHRlZF9pbihfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc09wdGVkSW4KICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5OQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwMAogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwMQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTAzLTEwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwNQogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzQ3JlYXRlZAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwNwogICAgLy8gX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTA2LTEwOAogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZCgKICAgIC8vICAgICBfZ2V0XzFzdF9yZWZfaW5kZXgoKQogICAgLy8gKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMDkKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTAKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cyhhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTEzLTExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTUKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYXNzZXRzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHMKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTYKICAgIC8vIHZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXggPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYXNzZXRzKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHMKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTcKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTgKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyMS0xMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjMKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYm94ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveGVzCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTI0CiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2JveGVzKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hlcwogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyNQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyNgogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyNwogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjktMTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlcyhzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzMQogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9ib3hfYnl0ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTMyCiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2JveF9ieXRlcyhfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQm94Qnl0ZXMKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzQKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzUKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + }, + "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.clear.teal b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal new file mode 100644 index 0000000..d07d34f --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAcctParamsGetContract.clear_state_program: + // tests/artifacts/StateOps/contract.py:24 + // class StateAcctParamsGetContract(ARC4Contract): + int 1 + return diff --git a/tests/artifacts/state-ops/data/StateAppParamsContract.approval.teal b/tests/artifacts/state-ops/data/StateAppParamsContract.approval.teal new file mode 100644 index 0000000..d7d91f2 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppParamsContract.approval.teal @@ -0,0 +1,547 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAppParamsContract.approval_program: + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@13 + 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 main_verify_app_params_get_approval_program_route@2 main_verify_app_params_get_clear_state_program_route@3 main_verify_app_params_get_global_num_uint_route@4 main_verify_app_params_get_global_num_byte_slice_route@5 main_verify_app_params_get_local_num_uint_route@6 main_verify_app_params_get_local_num_byte_slice_route@7 main_verify_app_params_get_extra_program_pages_route@8 main_verify_app_params_get_creator_route@9 main_verify_app_params_get_address_route@10 + err // reject transaction + +main_verify_app_params_get_approval_program_route@2: + // tests/artifacts/StateOps/contract.py:250 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + // tests/artifacts/StateOps/contract.py:250 + // @arc4.abimethod() + callsub verify_app_params_get_approval_program + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_app_params_get_clear_state_program_route@3: + // tests/artifacts/StateOps/contract.py:258 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + // tests/artifacts/StateOps/contract.py:258 + // @arc4.abimethod() + callsub verify_app_params_get_clear_state_program + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_app_params_get_global_num_uint_route@4: + // tests/artifacts/StateOps/contract.py:266 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + // tests/artifacts/StateOps/contract.py:266 + // @arc4.abimethod() + callsub verify_app_params_get_global_num_uint + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_app_params_get_global_num_byte_slice_route@5: + // tests/artifacts/StateOps/contract.py:274 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + // tests/artifacts/StateOps/contract.py:274 + // @arc4.abimethod() + callsub verify_app_params_get_global_num_byte_slice + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_app_params_get_local_num_uint_route@6: + // tests/artifacts/StateOps/contract.py:282 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + // tests/artifacts/StateOps/contract.py:282 + // @arc4.abimethod() + callsub verify_app_params_get_local_num_uint + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_app_params_get_local_num_byte_slice_route@7: + // tests/artifacts/StateOps/contract.py:290 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + // tests/artifacts/StateOps/contract.py:290 + // @arc4.abimethod() + callsub verify_app_params_get_local_num_byte_slice + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_app_params_get_extra_program_pages_route@8: + // tests/artifacts/StateOps/contract.py:298 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + // tests/artifacts/StateOps/contract.py:298 + // @arc4.abimethod() + callsub verify_app_params_get_extra_program_pages + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_app_params_get_creator_route@9: + // tests/artifacts/StateOps/contract.py:306 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + // tests/artifacts/StateOps/contract.py:306 + // @arc4.abimethod() + callsub verify_app_params_get_creator + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_app_params_get_address_route@10: + // tests/artifacts/StateOps/contract.py:314 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + // tests/artifacts/StateOps/contract.py:314 + // @arc4.abimethod() + callsub verify_app_params_get_address + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@13: + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_approval_program(a: uint64) -> bytes: +verify_app_params_get_approval_program: + // tests/artifacts/StateOps/contract.py:250-251 + // @arc4.abimethod() + // def verify_app_params_get_approval_program(self, a: Application) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:252 + // value, exists = op.AppParamsGet.app_approval_program(a) + frame_dig -1 + app_params_get AppApprovalProgram + swap + // tests/artifacts/StateOps/contract.py:253 + // value_index, exists_index = op.AppParamsGet.app_approval_program(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppApprovalProgram + cover 2 + // tests/artifacts/StateOps/contract.py:254 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:255 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:256 + // return value + retsub + + +// tests.artifacts.StateOps.contract._get_1st_ref_index() -> uint64: +_get_1st_ref_index: + // tests/artifacts/StateOps/contract.py:19-20 + // @subroutine + // def _get_1st_ref_index() -> UInt64: + proto 0 1 + // tests/artifacts/StateOps/contract.py:21 + // return op.btoi(Txn.application_args(1)) + txna ApplicationArgs 1 + btoi + retsub + + +// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_clear_state_program(a: uint64) -> bytes: +verify_app_params_get_clear_state_program: + // tests/artifacts/StateOps/contract.py:258-259 + // @arc4.abimethod() + // def verify_app_params_get_clear_state_program(self, a: Application) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:260 + // value, exists = op.AppParamsGet.app_clear_state_program(a) + frame_dig -1 + app_params_get AppClearStateProgram + swap + // tests/artifacts/StateOps/contract.py:261 + // value_index, exists_index = op.AppParamsGet.app_clear_state_program(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppClearStateProgram + cover 2 + // tests/artifacts/StateOps/contract.py:262 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:263 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:264 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_global_num_uint(a: uint64) -> uint64: +verify_app_params_get_global_num_uint: + // tests/artifacts/StateOps/contract.py:266-267 + // @arc4.abimethod() + // def verify_app_params_get_global_num_uint(self, a: Application) -> UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:268 + // value, exists = op.AppParamsGet.app_global_num_uint(a) + frame_dig -1 + app_params_get AppGlobalNumUint + swap + // tests/artifacts/StateOps/contract.py:269 + // value_index, exists_index = op.AppParamsGet.app_global_num_uint(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppGlobalNumUint + cover 2 + // tests/artifacts/StateOps/contract.py:270 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:271 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:272 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_global_num_byte_slice(a: uint64) -> uint64: +verify_app_params_get_global_num_byte_slice: + // tests/artifacts/StateOps/contract.py:274-275 + // @arc4.abimethod() + // def verify_app_params_get_global_num_byte_slice(self, a: Application) -> UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:276 + // value, exists = op.AppParamsGet.app_global_num_byte_slice(a) + frame_dig -1 + app_params_get AppGlobalNumByteSlice + swap + // tests/artifacts/StateOps/contract.py:277 + // value_index, exists_index = op.AppParamsGet.app_global_num_byte_slice(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppGlobalNumByteSlice + cover 2 + // tests/artifacts/StateOps/contract.py:278 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:279 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:280 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_local_num_uint(a: uint64) -> uint64: +verify_app_params_get_local_num_uint: + // tests/artifacts/StateOps/contract.py:282-283 + // @arc4.abimethod() + // def verify_app_params_get_local_num_uint(self, a: Application) -> UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:284 + // value, exists = op.AppParamsGet.app_local_num_uint(a) + frame_dig -1 + app_params_get AppLocalNumUint + swap + // tests/artifacts/StateOps/contract.py:285 + // value_index, exists_index = op.AppParamsGet.app_local_num_uint(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppLocalNumUint + cover 2 + // tests/artifacts/StateOps/contract.py:286 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:287 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:288 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_local_num_byte_slice(a: uint64) -> uint64: +verify_app_params_get_local_num_byte_slice: + // tests/artifacts/StateOps/contract.py:290-291 + // @arc4.abimethod() + // def verify_app_params_get_local_num_byte_slice(self, a: Application) -> UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:292 + // value, exists = op.AppParamsGet.app_local_num_byte_slice(a) + frame_dig -1 + app_params_get AppLocalNumByteSlice + swap + // tests/artifacts/StateOps/contract.py:293 + // value_index, exists_index = op.AppParamsGet.app_local_num_byte_slice(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppLocalNumByteSlice + cover 2 + // tests/artifacts/StateOps/contract.py:294 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:295 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:296 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_extra_program_pages(a: uint64) -> uint64: +verify_app_params_get_extra_program_pages: + // tests/artifacts/StateOps/contract.py:298-299 + // @arc4.abimethod() + // def verify_app_params_get_extra_program_pages(self, a: Application) -> UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:300 + // value, exists = op.AppParamsGet.app_extra_program_pages(a) + frame_dig -1 + app_params_get AppExtraProgramPages + swap + // tests/artifacts/StateOps/contract.py:301 + // value_index, exists_index = op.AppParamsGet.app_extra_program_pages(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppExtraProgramPages + cover 2 + // tests/artifacts/StateOps/contract.py:302 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:303 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:304 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_creator(a: uint64) -> bytes: +verify_app_params_get_creator: + // tests/artifacts/StateOps/contract.py:306-307 + // @arc4.abimethod() + // def verify_app_params_get_creator(self, a: Application) -> arc4.Address: + proto 1 1 + // tests/artifacts/StateOps/contract.py:308 + // value, exists = op.AppParamsGet.app_creator(a) + frame_dig -1 + app_params_get AppCreator + swap + // tests/artifacts/StateOps/contract.py:309 + // value_index, exists_index = op.AppParamsGet.app_creator(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppCreator + cover 2 + // tests/artifacts/StateOps/contract.py:310 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:311 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:312 + // return arc4.Address(value) + retsub + + +// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_address(a: uint64) -> bytes: +verify_app_params_get_address: + // tests/artifacts/StateOps/contract.py:314-315 + // @arc4.abimethod() + // def verify_app_params_get_address(self, a: Application) -> arc4.Address: + proto 1 1 + // tests/artifacts/StateOps/contract.py:316 + // value, exists = op.AppParamsGet.app_address(a) + frame_dig -1 + app_params_get AppAddress + swap + // tests/artifacts/StateOps/contract.py:317 + // value_index, exists_index = op.AppParamsGet.app_address(_get_1st_ref_index()) + callsub _get_1st_ref_index + app_params_get AppAddress + cover 2 + // tests/artifacts/StateOps/contract.py:318 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:319 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:320 + // return arc4.Address(value) + retsub diff --git a/tests/artifacts/state-ops/data/StateAppParamsContract.arc32.json b/tests/artifacts/state-ops/data/StateAppParamsContract.arc32.json new file mode 100644 index 0000000..76ab2a1 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppParamsContract.arc32.json @@ -0,0 +1,199 @@ +{ + "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": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBQYXJhbXNDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDEzCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtKGFwcGxpY2F0aW9uKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0oYXBwbGljYXRpb24pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50KGFwcGxpY2F0aW9uKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludChhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGFwcGxpY2F0aW9uKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXBwbGljYXRpb24pYWRkcmVzcyIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3MoYXBwbGljYXRpb24pYWRkcmVzcyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW1fcm91dGVAMiBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtX3JvdXRlQDMgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50X3JvdXRlQDQgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDUgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnRfcm91dGVANiBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3IG1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXNfcm91dGVAOCBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yX3JvdXRlQDkgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzc19yb3V0ZUAxMAogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfYXBwcm92YWxfcHJvZ3JhbV9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW0KICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjc0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjc0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlcwogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfY3JlYXRvcl9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Nfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzcwogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQ4CiAgICAvLyBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW0oYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUwLTI1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYXBwcm92YWxfcHJvZ3JhbShzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTIKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2FwcHJvdmFsX3Byb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQXBwcm92YWxQcm9ncmFtCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUzCiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9hcHByb3ZhbF9wcm9ncmFtKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEFwcHJvdmFsUHJvZ3JhbQogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1NAogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1NQogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1NgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuX2dldF8xc3RfcmVmX2luZGV4KCkgLT4gdWludDY0OgpfZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTktMjAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgX2dldF8xc3RfcmVmX2luZGV4KCkgLT4gVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjEKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbl9hcmdzKDEpKQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0oYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjU4LTI1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbShzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjAKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2NsZWFyX3N0YXRlX3Byb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjEKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2NsZWFyX3N0YXRlX3Byb2dyYW0oX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjIKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjMKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludChhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjYtMjY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2OAogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfZ2xvYmFsX251bV91aW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEdsb2JhbE51bVVpbnQKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjkKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2dsb2JhbF9udW1fdWludChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1VaW50CiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjcwCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjcxCiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjcyCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2UoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjc0LTI3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlKHNlbGYsIGE6IEFwcGxpY2F0aW9uKSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzYKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2dsb2JhbF9udW1fYnl0ZV9zbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1CeXRlU2xpY2UKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzcKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2dsb2JhbF9udW1fYnl0ZV9zbGljZShfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1CeXRlU2xpY2UKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzgKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzkKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODAKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjgyLTI4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4NAogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfbG9jYWxfbnVtX3VpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwTG9jYWxOdW1VaW50CiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjg1CiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9sb2NhbF9udW1fdWludChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBMb2NhbE51bVVpbnQKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODYKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODcKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODgKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjkwLTI5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2Uoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5MgogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfbG9jYWxfbnVtX2J5dGVfc2xpY2UoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwTG9jYWxOdW1CeXRlU2xpY2UKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTMKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2xvY2FsX251bV9ieXRlX3NsaWNlKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcExvY2FsTnVtQnl0ZVNsaWNlCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk0CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk1CiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk2CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTgtMjk5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKHNlbGYsIGE6IEFwcGxpY2F0aW9uKSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDAKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2V4dHJhX3Byb2dyYW1fcGFnZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDEKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2V4dHJhX3Byb2dyYW1fcGFnZXMoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDIKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDMKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzA2LTMwNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY3JlYXRvcihzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzA4CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9jcmVhdG9yKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcENyZWF0b3IKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDkKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2NyZWF0b3IoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwQ3JlYXRvcgogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxMAogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxMQogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxMgogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxNC0zMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Moc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxNgogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfYWRkcmVzcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBBZGRyZXNzCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzE3CiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9hZGRyZXNzKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEFkZHJlc3MKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTgKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTkKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjAKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBQYXJhbXNDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + }, + "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.clear.teal b/tests/artifacts/state-ops/data/StateAppParamsContract.clear.teal new file mode 100644 index 0000000..d499707 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppParamsContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAppParamsContract.clear_state_program: + // tests/artifacts/StateOps/contract.py:248 + // class StateAppParamsContract(ARC4Contract): + int 1 + return diff --git a/tests/artifacts/state-ops/data/StateAssetHoldingContract.approval.teal b/tests/artifacts/state-ops/data/StateAssetHoldingContract.approval.teal new file mode 100644 index 0000000..6b077bd --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAssetHoldingContract.approval.teal @@ -0,0 +1,115 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAssetHoldingContract.approval_program: + // tests/artifacts/StateOps/contract.py:138 + // class StateAssetHoldingContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@6 + method "verify_asset_holding_get(account,asset)uint64" + method "verify_asset_frozen_get(account,asset)bool" + txna ApplicationArgs 0 + match main_verify_asset_holding_get_route@2 main_verify_asset_frozen_get_route@3 + err // reject transaction + +main_verify_asset_holding_get_route@2: + // tests/artifacts/StateOps/contract.py:139 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:138 + // class StateAssetHoldingContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:139 + // @arc4.abimethod() + callsub verify_asset_holding_get + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_frozen_get_route@3: + // tests/artifacts/StateOps/contract.py:144 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:138 + // class StateAssetHoldingContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:144 + // @arc4.abimethod() + callsub verify_asset_frozen_get + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@6: + // tests/artifacts/StateOps/contract.py:138 + // class StateAssetHoldingContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.StateOps.contract.StateAssetHoldingContract.verify_asset_holding_get(a: bytes, b: uint64) -> uint64: +verify_asset_holding_get: + // tests/artifacts/StateOps/contract.py:139-140 + // @arc4.abimethod() + // def verify_asset_holding_get(self, a: Account, b: Asset) -> UInt64: + proto 2 1 + // tests/artifacts/StateOps/contract.py:141 + // balance, _val = op.AssetHoldingGet.asset_balance(a, b) + frame_dig -2 + frame_dig -1 + asset_holding_get AssetBalance + pop + // tests/artifacts/StateOps/contract.py:142 + // return balance + retsub + + +// tests.artifacts.StateOps.contract.StateAssetHoldingContract.verify_asset_frozen_get(a: bytes, b: uint64) -> uint64: +verify_asset_frozen_get: + // tests/artifacts/StateOps/contract.py:144-145 + // @arc4.abimethod() + // def verify_asset_frozen_get(self, a: Account, b: Asset) -> bool: + proto 2 1 + // tests/artifacts/StateOps/contract.py:146 + // frozen, _val = op.AssetHoldingGet.asset_frozen(a, b) + frame_dig -2 + frame_dig -1 + asset_holding_get AssetFrozen + pop + // tests/artifacts/StateOps/contract.py:147 + // return frozen + retsub diff --git a/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc32.json b/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc32.json new file mode 100644 index 0000000..a7b0497 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc32.json @@ -0,0 +1,81 @@ +{ + "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": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzOAogICAgLy8gY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDYKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0KGFjY291bnQsYXNzZXQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfZnJvemVuX2dldChhY2NvdW50LGFzc2V0KWJvb2wiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX3ZlcmlmeV9hc3NldF9ob2xkaW5nX2dldF9yb3V0ZUAyIG1haW5fdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXRfcm91dGVAMwogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXRfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM4CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXRfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM4CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfZnJvemVuX2dldAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM4CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzOS0xNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0KHNlbGYsIGE6IEFjY291bnQsIGI6IEFzc2V0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDEKICAgIC8vIGJhbGFuY2UsIF92YWwgPSBvcC5Bc3NldEhvbGRpbmdHZXQuYXNzZXRfYmFsYW5jZShhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQyCiAgICAvLyByZXR1cm4gYmFsYW5jZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfZnJvemVuX2dldDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDQtMTQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0KHNlbGYsIGE6IEFjY291bnQsIGI6IEFzc2V0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQ2CiAgICAvLyBmcm96ZW4sIF92YWwgPSBvcC5Bc3NldEhvbGRpbmdHZXQuYXNzZXRfZnJvemVuKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRGcm96ZW4KICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0NwogICAgLy8gcmV0dXJuIGZyb3plbgogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzOAogICAgLy8gY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + }, + "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.clear.teal b/tests/artifacts/state-ops/data/StateAssetHoldingContract.clear.teal new file mode 100644 index 0000000..ec6efc8 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAssetHoldingContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAssetHoldingContract.clear_state_program: + // tests/artifacts/StateOps/contract.py:138 + // class StateAssetHoldingContract(ARC4Contract): + int 1 + return diff --git a/tests/artifacts/state-ops/data/StateAssetParamsContract.approval.teal b/tests/artifacts/state-ops/data/StateAssetParamsContract.approval.teal new file mode 100644 index 0000000..b0cda94 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAssetParamsContract.approval.teal @@ -0,0 +1,725 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAssetParamsContract.approval_program: + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@16 + 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 main_verify_asset_params_get_total_route@2 main_verify_asset_params_get_decimals_route@3 main_verify_asset_params_get_default_frozen_route@4 main_verify_asset_params_get_unit_name_route@5 main_verify_asset_params_get_name_route@6 main_verify_asset_params_get_url_route@7 main_verify_asset_params_get_metadata_hash_route@8 main_verify_asset_params_get_manager_route@9 main_verify_asset_params_get_reserve_route@10 main_verify_asset_params_get_freeze_route@11 main_verify_asset_params_get_clawback_route@12 main_verify_asset_params_get_creator_route@13 + err // reject transaction + +main_verify_asset_params_get_total_route@2: + // tests/artifacts/StateOps/contract.py:151 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:151 + // @arc4.abimethod() + callsub verify_asset_params_get_total + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_decimals_route@3: + // tests/artifacts/StateOps/contract.py:159 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:159 + // @arc4.abimethod() + callsub verify_asset_params_get_decimals + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_default_frozen_route@4: + // tests/artifacts/StateOps/contract.py:167 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:167 + // @arc4.abimethod() + callsub verify_asset_params_get_default_frozen + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_unit_name_route@5: + // tests/artifacts/StateOps/contract.py:175 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:175 + // @arc4.abimethod() + callsub verify_asset_params_get_unit_name + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_name_route@6: + // tests/artifacts/StateOps/contract.py:183 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:183 + // @arc4.abimethod() + callsub verify_asset_params_get_name + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_url_route@7: + // tests/artifacts/StateOps/contract.py:191 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:191 + // @arc4.abimethod() + callsub verify_asset_params_get_url + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_metadata_hash_route@8: + // tests/artifacts/StateOps/contract.py:199 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:199 + // @arc4.abimethod() + callsub verify_asset_params_get_metadata_hash + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_manager_route@9: + // tests/artifacts/StateOps/contract.py:207 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:207 + // @arc4.abimethod() + callsub verify_asset_params_get_manager + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_reserve_route@10: + // tests/artifacts/StateOps/contract.py:215 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:215 + // @arc4.abimethod() + callsub verify_asset_params_get_reserve + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_freeze_route@11: + // tests/artifacts/StateOps/contract.py:223 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:223 + // @arc4.abimethod() + callsub verify_asset_params_get_freeze + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_clawback_route@12: + // tests/artifacts/StateOps/contract.py:231 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:231 + // @arc4.abimethod() + callsub verify_asset_params_get_clawback + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_asset_params_get_creator_route@13: + // tests/artifacts/StateOps/contract.py:239 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Assets + // tests/artifacts/StateOps/contract.py:239 + // @arc4.abimethod() + callsub verify_asset_params_get_creator + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_bare_routing@16: + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_total(a: uint64) -> uint64: +verify_asset_params_get_total: + // tests/artifacts/StateOps/contract.py:151-152 + // @arc4.abimethod() + // def verify_asset_params_get_total(self, a: Asset) -> UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:153 + // value, exists = op.AssetParamsGet.asset_total(a) + frame_dig -1 + asset_params_get AssetTotal + swap + // tests/artifacts/StateOps/contract.py:154 + // value_index, exists_index = op.AssetParamsGet.asset_total(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetTotal + cover 2 + // tests/artifacts/StateOps/contract.py:155 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:156 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:157 + // return value + retsub + + +// tests.artifacts.StateOps.contract._get_1st_ref_index() -> uint64: +_get_1st_ref_index: + // tests/artifacts/StateOps/contract.py:19-20 + // @subroutine + // def _get_1st_ref_index() -> UInt64: + proto 0 1 + // tests/artifacts/StateOps/contract.py:21 + // return op.btoi(Txn.application_args(1)) + txna ApplicationArgs 1 + btoi + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_decimals(a: uint64) -> uint64: +verify_asset_params_get_decimals: + // tests/artifacts/StateOps/contract.py:159-160 + // @arc4.abimethod() + // def verify_asset_params_get_decimals(self, a: Asset) -> UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:161 + // value, exists = op.AssetParamsGet.asset_decimals(a) + frame_dig -1 + asset_params_get AssetDecimals + swap + // tests/artifacts/StateOps/contract.py:162 + // value_index, exists_index = op.AssetParamsGet.asset_decimals(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetDecimals + cover 2 + // tests/artifacts/StateOps/contract.py:163 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:164 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:165 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_default_frozen(a: uint64) -> uint64: +verify_asset_params_get_default_frozen: + // tests/artifacts/StateOps/contract.py:167-168 + // @arc4.abimethod() + // def verify_asset_params_get_default_frozen(self, a: Asset) -> bool: + proto 1 1 + // tests/artifacts/StateOps/contract.py:169 + // value, exists = op.AssetParamsGet.asset_default_frozen(a) + frame_dig -1 + asset_params_get AssetDefaultFrozen + swap + // tests/artifacts/StateOps/contract.py:170 + // value_index, exists_index = op.AssetParamsGet.asset_default_frozen(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetDefaultFrozen + cover 2 + // tests/artifacts/StateOps/contract.py:171 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:172 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:173 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_unit_name(a: uint64) -> bytes: +verify_asset_params_get_unit_name: + // tests/artifacts/StateOps/contract.py:175-176 + // @arc4.abimethod() + // def verify_asset_params_get_unit_name(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:177 + // value, exists = op.AssetParamsGet.asset_unit_name(a) + frame_dig -1 + asset_params_get AssetUnitName + swap + // tests/artifacts/StateOps/contract.py:178 + // value_index, exists_index = op.AssetParamsGet.asset_unit_name(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetUnitName + cover 2 + // tests/artifacts/StateOps/contract.py:179 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:180 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:181 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_name(a: uint64) -> bytes: +verify_asset_params_get_name: + // tests/artifacts/StateOps/contract.py:183-184 + // @arc4.abimethod() + // def verify_asset_params_get_name(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:185 + // value, exists = op.AssetParamsGet.asset_name(a) + frame_dig -1 + asset_params_get AssetName + swap + // tests/artifacts/StateOps/contract.py:186 + // value_index, exists_index = op.AssetParamsGet.asset_name(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetName + cover 2 + // tests/artifacts/StateOps/contract.py:187 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:188 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:189 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_url(a: uint64) -> bytes: +verify_asset_params_get_url: + // tests/artifacts/StateOps/contract.py:191-192 + // @arc4.abimethod() + // def verify_asset_params_get_url(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:193 + // value, exists = op.AssetParamsGet.asset_url(a) + frame_dig -1 + asset_params_get AssetURL + swap + // tests/artifacts/StateOps/contract.py:194 + // value_index, exists_index = op.AssetParamsGet.asset_url(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetURL + cover 2 + // tests/artifacts/StateOps/contract.py:195 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:196 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:197 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_metadata_hash(a: uint64) -> bytes: +verify_asset_params_get_metadata_hash: + // tests/artifacts/StateOps/contract.py:199-200 + // @arc4.abimethod() + // def verify_asset_params_get_metadata_hash(self, a: Asset) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:201 + // value, exists = op.AssetParamsGet.asset_metadata_hash(a) + frame_dig -1 + asset_params_get AssetMetadataHash + swap + // tests/artifacts/StateOps/contract.py:202 + // value_index, exists_index = op.AssetParamsGet.asset_metadata_hash(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetMetadataHash + cover 2 + // tests/artifacts/StateOps/contract.py:203 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:204 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:205 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_manager(a: uint64) -> bytes: +verify_asset_params_get_manager: + // tests/artifacts/StateOps/contract.py:207-208 + // @arc4.abimethod() + // def verify_asset_params_get_manager(self, a: Asset) -> arc4.Address: + proto 1 1 + // tests/artifacts/StateOps/contract.py:209 + // value, exists = op.AssetParamsGet.asset_manager(a) + frame_dig -1 + asset_params_get AssetManager + swap + // tests/artifacts/StateOps/contract.py:210 + // value_index, exists_index = op.AssetParamsGet.asset_manager(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetManager + cover 2 + // tests/artifacts/StateOps/contract.py:211 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:212 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:213 + // return arc4.Address(value) + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_reserve(a: uint64) -> bytes: +verify_asset_params_get_reserve: + // tests/artifacts/StateOps/contract.py:215-216 + // @arc4.abimethod() + // def verify_asset_params_get_reserve(self, a: Asset) -> arc4.Address: + proto 1 1 + // tests/artifacts/StateOps/contract.py:217 + // value, exists = op.AssetParamsGet.asset_reserve(a) + frame_dig -1 + asset_params_get AssetReserve + swap + // tests/artifacts/StateOps/contract.py:218 + // value_index, exists_index = op.AssetParamsGet.asset_reserve(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetReserve + cover 2 + // tests/artifacts/StateOps/contract.py:219 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:220 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:221 + // return arc4.Address(value) + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_freeze(a: uint64) -> bytes: +verify_asset_params_get_freeze: + // tests/artifacts/StateOps/contract.py:223-224 + // @arc4.abimethod() + // def verify_asset_params_get_freeze(self, a: Asset) -> arc4.Address: + proto 1 1 + // tests/artifacts/StateOps/contract.py:225 + // value, exists = op.AssetParamsGet.asset_freeze(a) + frame_dig -1 + asset_params_get AssetFreeze + swap + // tests/artifacts/StateOps/contract.py:226 + // value_index, exists_index = op.AssetParamsGet.asset_freeze(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetFreeze + cover 2 + // tests/artifacts/StateOps/contract.py:227 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:228 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:229 + // return arc4.Address(value) + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_clawback(a: uint64) -> bytes: +verify_asset_params_get_clawback: + // tests/artifacts/StateOps/contract.py:231-232 + // @arc4.abimethod() + // def verify_asset_params_get_clawback(self, a: Asset) -> arc4.Address: + proto 1 1 + // tests/artifacts/StateOps/contract.py:233 + // value, exists = op.AssetParamsGet.asset_clawback(a) + frame_dig -1 + asset_params_get AssetClawback + swap + // tests/artifacts/StateOps/contract.py:234 + // value_index, exists_index = op.AssetParamsGet.asset_clawback(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetClawback + cover 2 + // tests/artifacts/StateOps/contract.py:235 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:236 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:237 + // return arc4.Address(value) + retsub + + +// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_creator(a: uint64) -> bytes: +verify_asset_params_get_creator: + // tests/artifacts/StateOps/contract.py:239-240 + // @arc4.abimethod() + // def verify_asset_params_get_creator(self, a: Asset) -> arc4.Address: + proto 1 1 + // tests/artifacts/StateOps/contract.py:241 + // value, exists = op.AssetParamsGet.asset_creator(a) + frame_dig -1 + asset_params_get AssetCreator + swap + // tests/artifacts/StateOps/contract.py:242 + // value_index, exists_index = op.AssetParamsGet.asset_creator(_get_1st_ref_index()) + callsub _get_1st_ref_index + asset_params_get AssetCreator + cover 2 + // tests/artifacts/StateOps/contract.py:243 + // assert value == value_index, "expected value by index to match" + dig 1 + == + assert // expected value by index to match + // tests/artifacts/StateOps/contract.py:244 + // assert exists == exists_index, "expected exists by index to match" + cover 2 + == + assert // expected exists by index to match + // tests/artifacts/StateOps/contract.py:245 + // return arc4.Address(value) + retsub diff --git a/tests/artifacts/state-ops/data/StateAssetParamsContract.arc32.json b/tests/artifacts/state-ops/data/StateAssetParamsContract.arc32.json new file mode 100644 index 0000000..04e164b --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAssetParamsContract.arc32.json @@ -0,0 +1,253 @@ +{ + "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": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxNgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbChhc3NldCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGFzc2V0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW4oYXNzZXQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lKGFzc2V0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZShhc3NldClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybChhc3NldClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2goYXNzZXQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyKGFzc2V0KWFkZHJlc3MiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYXNzZXQpYWRkcmVzcyIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplKGFzc2V0KWFkZHJlc3MiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrKGFzc2V0KWFkZHJlc3MiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXNzZXQpYWRkcmVzcyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMiBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzX3JvdXRlQDMgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbl9yb3V0ZUA0IG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDUgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lX3JvdXRlQDYgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91cmxfcm91dGVANyBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2hfcm91dGVAOCBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXJfcm91dGVAOSBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmVfcm91dGVAMTAgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemVfcm91dGVAMTEgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxMiBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAMTMKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWwKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW5fcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW4KICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTAKICAgIC8vIGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWVfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTkxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MAogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaF9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTAKICAgIC8vIGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MAogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemVfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MAogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2sKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcl9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTEtMTUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKHNlbGYsIGE6IEFzc2V0KSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTMKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF90b3RhbChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VG90YWwKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTQKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF90b3RhbChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VG90YWwKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTUKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTYKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Ll9nZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKX2dldF8xc3RfcmVmX2luZGV4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5LTIwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9nZXRfMXN0X3JlZl9pbmRleCgpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxCiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25fYXJncygxKSkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1OS0xNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMoc2VsZiwgYTogQXNzZXQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2MQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2RlY2ltYWxzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXREZWNpbWFscwogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2MgogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2RlY2ltYWxzKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXREZWNpbWFscwogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2MwogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2NAogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2NQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNjctMTY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuKHNlbGYsIGE6IEFzc2V0KSAtPiBib29sOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTY5CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfZGVmYXVsdF9mcm96ZW4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlZmF1bHRGcm96ZW4KICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzAKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9kZWZhdWx0X2Zyb3plbihfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RGVmYXVsdEZyb3plbgogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3MQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3MgogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3MwogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc1LTE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUoc2VsZiwgYTogQXNzZXQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc3CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfdW5pdF9uYW1lKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRVbml0TmFtZQogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3OAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3VuaXRfbmFtZShfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VW5pdE5hbWUKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzkKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODAKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTgzLTE4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKHNlbGYsIGE6IEFzc2V0KSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4NQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X25hbWUoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODYKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9uYW1lKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXROYW1lCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTg3CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTg4CiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTg5CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTEtMTkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybChzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTMKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF91cmwoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFVSTAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5NAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3VybChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VVJMCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk1CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk2CiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk3CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5OS0yMDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDEKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tZXRhZGF0YV9oYXNoKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDIKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tZXRhZGF0YV9oYXNoKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDQKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDUKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjA3LTIwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyKHNlbGYsIGE6IEFzc2V0KSAtPiBhcmM0LkFkZHJlc3M6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDkKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tYW5hZ2VyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNYW5hZ2VyCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjEwCiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfbWFuYWdlcihfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0TWFuYWdlcgogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxMQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxMgogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxMwogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9yZXNlcnZlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxNS0yMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZShzZWxmLCBhOiBBc3NldCkgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjE3CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfcmVzZXJ2ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0UmVzZXJ2ZQogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxOAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3Jlc2VydmUoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFJlc2VydmUKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTkKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjAKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjEKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjIzLTIyNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoc2VsZiwgYTogQXNzZXQpIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyNQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2ZyZWV6ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RnJlZXplCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjI2CiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfZnJlZXplKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRGcmVlemUKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjcKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjgKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjkKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzMS0yMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2soc2VsZiwgYTogQXNzZXQpIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzMwogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2NsYXdiYWNrKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDbGF3YmFjawogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzNAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2NsYXdiYWNrKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDbGF3YmFjawogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzNQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzNgogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzNwogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcihhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jcmVhdG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOS0yNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcihzZWxmLCBhOiBBc3NldCkgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQxCiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfY3JlYXRvcihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0Q3JlYXRvcgogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0MgogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2NyZWF0b3IoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldENyZWF0b3IKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDQKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDUKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + }, + "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.clear.teal b/tests/artifacts/state-ops/data/StateAssetParamsContract.clear.teal new file mode 100644 index 0000000..21cbde0 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAssetParamsContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAssetParamsContract.clear_state_program: + // tests/artifacts/StateOps/contract.py:150 + // class StateAssetParamsContract(ARC4Contract): + int 1 + return diff --git a/tests/avm-invoker.ts b/tests/avm-invoker.ts new file mode 100644 index 0000000..4c606f5 --- /dev/null +++ b/tests/avm-invoker.ts @@ -0,0 +1,136 @@ +import { internal, uint64 } from '@algorandfoundation/algo-ts' +import * as algokit from '@algorandfoundation/algokit-utils' +import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' +import { ABIAppCallArg, ABIReturn } from '@algorandfoundation/algokit-utils/types/app' +import { ApplicationClient } from '@algorandfoundation/algokit-utils/types/app-client' +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { KmdAccountManager } from '@algorandfoundation/algokit-utils/types/kmd-account-manager' +import { nullLogger } from '@algorandfoundation/algokit-utils/types/logging' +import { SendTransactionFrom, SendTransactionParams } from '@algorandfoundation/algokit-utils/types/transaction' +import { ABIValue, Account as algoSdkAccount, generateAccount } from 'algosdk' +import { randomUUID } from 'crypto' +import { asUint64, getRandomNumber, Lazy } from '../src/util' + +algokit.Config.configure({ logger: nullLogger }) +const ARC4_PREFIX_LENGTH = 2 +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 client = algorandClient() + const defaultSigner = await client.account.kmd.getLocalNetDispenserAccount() + const appClient = algokit.getAppClient({ app: appSpec, resolveBy: 'id', id: 0, sender: defaultSigner.account }, client.client.algod) + const app = await appClient.create({ note: randomUUID() }) + return [appClient, app] as const +} + +const inovkeMethod = async ( + appClient: ApplicationClient, + method: string, + sendParams?: SendTransactionParams, + ...methodArgs: ABIAppCallArg[] +): Promise => { + const response = await appClient.call({ method, methodArgs, note: randomUUID(), sendParams }) + if (!response.return) { + throw new Error(`${method} did not return a value`) + } + if (response.return.decodeError) { + throw response.return.decodeError + } + return response.return +} + +export const getAvmResult = async ( + { appClient, sendParams }: { appClient: ApplicationClient; sendParams?: SendTransactionParams }, + method: string, + ...methodArgs: ABIAppCallArg[] +): Promise => { + const result = await inovkeMethod(appClient, method, sendParams, ...methodArgs) + return result.returnValue as TResult +} + +export const getAvmResultRaw = async ( + { appClient, sendParams }: { appClient: ApplicationClient; sendParams?: SendTransactionParams }, + method: string, + ...methodArgs: ABIAppCallArg[] +): Promise => { + const result = await inovkeMethod(appClient, method, sendParams, ...methodArgs) + return result.rawReturnValue?.slice(ARC4_PREFIX_LENGTH) +} + +export const getLocalNetDefaultAccount = () => { + const client = algorandClient() + const kmdAccountManager = new KmdAccountManager(client.client) + return kmdAccountManager.getLocalNetDispenserAccount() +} + +export const generateTestAccount = async (): Promise => { + const account = generateAccount() + + await algokit.ensureFunded( + { + accountToFund: account, + minSpendingBalance: AlgoAmount.MicroAlgos(INITIAL_BALANCE_MICRO_ALGOS), + }, + algorandClient().client.algod, + ) + return account +} + +export const generateTestAsset = async (fields: { + creator: SendTransactionFrom + total?: number | bigint + decimals?: number + name?: string + unit?: string + url?: string + metadataHash?: string + manager?: SendTransactionFrom + reserveAccount?: SendTransactionFrom + freezeAccount?: SendTransactionFrom + clawbackAccount?: SendTransactionFrom + frozenByDefault?: boolean +}): Promise => { + const client = algorandClient() + if (fields.total === undefined) { + fields.total = getRandomNumber(20, 120) + } + + if (fields.name === undefined) { + fields.name = `ASA ${getRandomNumber(1, 100)}_${getRandomNumber(1, 100)}_${fields.total}` + } + + if (fields.decimals === undefined) { + fields.decimals = 0 + } + const params = await client.getSuggestedParams() + const x = await algokit.createAsset( + { + creator: fields.creator, + total: BigInt(fields.total) * 10n ** BigInt(fields.decimals), + decimals: fields.decimals, + name: fields.name, + unit: fields.unit ?? '', + url: fields.url ?? 'https://algorand.co', + metadataHash: fields.metadataHash, + manager: fields.manager, + reserveAccount: fields.reserveAccount, + freezeAccount: fields.freezeAccount, + clawbackAccount: fields.clawbackAccount, + frozenByDefault: fields.frozenByDefault ?? false, + transactionParams: params, + note: randomUUID(), + }, + client.client.algod, + ) + if (x.confirmation === 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 new file mode 100644 index 0000000..0a76f42 --- /dev/null +++ b/tests/crypto-op-codes.spec.ts @@ -0,0 +1,316 @@ +import { Bytes, internal, op as publicOps, uint64 } from '@algorandfoundation/algo-ts' +import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import algosdk from 'algosdk' +import { ec } from 'elliptic' +import { keccak256 as js_keccak256 } from 'js-sha3' +import nacl from 'tweetnacl' +import { afterEach, describe, expect, it, Mock, test, vi } from 'vitest' +import { TestExecutionContext } from '../src' +import { MAX_BYTES_SIZE } from '../src/constants' +import * as op from '../src/impl/crypto' +import appSpecJson from './artifacts/crypto-ops/data/CryptoOpsContract.arc32.json' +import { getAlgorandAppClientWithApp, getAvmResult, getAvmResultRaw } from './avm-invoker' +import { asUint8Array, getPaddedUint8Array } from './util' + +const MAX_ARG_LEN = 2048 +const curveMap = { + [internal.opTypes.Ecdsa.Secp256k1]: 'secp256k1', + [internal.opTypes.Ecdsa.Secp256r1]: 'p256', +} + +vi.mock('../src/impl/crypto', async (importOriginal) => { + const mod = await importOriginal() + return { + ...mod, + mockedVrfVerify: vi.fn(), + } +}) +describe('crypto op codes', async () => { + const [appClient, app] = await getAlgorandAppClientWithApp(appSpecJson as AppSpec) + const ctx = new TestExecutionContext() + + afterEach(async () => { + ctx.reset() + }) + + describe('sha256', async () => { + test.each([ + ['', 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 getAvmResultRaw({ appClient }, 'verify_sha256', asUint8Array(a), padSize))! + const paddedA = getPaddedUint8Array(padSize, a) + const result = op.sha256(paddedA) + expect(asUint8Array(result)).toEqual(avmResult) + }) + }) + + describe('sha3_256', async () => { + test.each([ + ['', 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 getAvmResultRaw({ appClient }, 'verify_sha3_256', asUint8Array(a), padSize))! + const paddedA = getPaddedUint8Array(padSize, a) + const result = op.sha3_256(paddedA) + expect(asUint8Array(result)).toEqual(avmResult) + }) + }) + + describe('keccak256', async () => { + test.each([ + ['', 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 getAvmResultRaw({ appClient }, 'verify_keccak_256', asUint8Array(a), padSize))! + const paddedA = getPaddedUint8Array(padSize, a) + const result = op.keccak256(paddedA) + expect(asUint8Array(result)).toEqual(avmResult) + expect(result.length.valueOf()).toBe(32n) + }) + }) + + describe('sha512_256', async () => { + test.each([ + ['', 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 getAvmResultRaw({ appClient }, 'verify_sha512_256', asUint8Array(a), padSize))! + const paddedA = getPaddedUint8Array(padSize, a) + const result = op.sha512_256(paddedA) + expect(asUint8Array(result)).toEqual(avmResult) + expect(result.length.valueOf()).toBe(32n) + }) + }) + + describe('ed25519verifyBare', async () => { + it('should return true for valid signature', async () => { + 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( + { appClient, sendParams: { fee: AlgoAmount.Algos(2000) } }, + 'verify_ed25519verify_bare', + asUint8Array(message), + signature, + keyPair.publicKey, + ) + const result = op.ed25519verifyBare(message, signature, keyPair.publicKey) + expect(result).toEqual(avmResult) + }) + }) + + describe('ed25519verify', async () => { + it('should return true for valid signature', async () => { + const approval = app.compiledApproval + const appCallTxn = ctx.any.txn.applicationCall({ + approvalProgram: Bytes(approval.compiledBase64ToBytes), + }) + + const message = Bytes('Test message for ed25519 verification') + const account = algosdk.generateAccount() + const publicKey = algosdk.decodeAddress(account.addr).publicKey + const signature = algosdk.tealSignFromProgram(account.sk, asUint8Array(message), approval.compiledBase64ToBytes) + + const avmResult = await getAvmResult( + { appClient, sendParams: { fee: AlgoAmount.Algos(2000) } }, + 'verify_ed25519verify', + asUint8Array(message), + signature, + publicKey, + ) + + ctx.txn.createScope([appCallTxn]).execute(() => { + const result = op.ed25519verify(message, signature, publicKey) + expect(result).toEqual(avmResult) + }) + }) + it('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 () => { + 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: { fee: AlgoAmount.Algos(5000) } }, + 'verify_ecdsa_verify_k1', + asUint8Array(messageHash), + asUint8Array(sigR), + asUint8Array(sigS), + asUint8Array(pubkeyX), + asUint8Array(pubkeyY), + ) + const result = op.ecdsaVerify(internal.opTypes.Ecdsa.Secp256k1, messageHash, sigR, sigS, pubkeyX, pubkeyY) + + expect(result).toEqual(avmResult) + }) + it('should be able to verify r1 signature', async () => { + 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: { fee: AlgoAmount.Algos(5000) } }, + 'verify_ecdsa_verify_r1', + asUint8Array(messageHash), + asUint8Array(sigR), + asUint8Array(sigS), + asUint8Array(pubkeyX), + asUint8Array(pubkeyY), + ) + const result = op.ecdsaVerify(internal.opTypes.Ecdsa.Secp256r1, messageHash, sigR, sigS, pubkeyX, pubkeyY) + + expect(result).toEqual(avmResult) + }) + }) + + describe('ecdsaPkRecover', async () => { + it('should be able to recover k1 public key', async () => { + const testData = generateEcdsaTestData(internal.opTypes.Ecdsa.Secp256k1) + const a = testData.data + const b = testData.recoveryId + const c = testData.r + const d = testData.s + const avmResult = await getAvmResult( + { appClient, sendParams: { fee: AlgoAmount.Algos(5000) } }, + 'verify_ecdsa_recover_k1', + asUint8Array(a), + b.asNumber(), + asUint8Array(c), + asUint8Array(d), + ) + const result = op.ecdsaPkRecover(internal.opTypes.Ecdsa.Secp256k1, a, b, c, d) + + expect(asUint8Array(result[0])).toEqual(new Uint8Array(avmResult[0])) + expect(asUint8Array(result[1])).toEqual(new Uint8Array(avmResult[1])) + }) + + it('should throw unsupported error when trying to recover r1 public key', async () => { + const testData = generateEcdsaTestData(internal.opTypes.Ecdsa.Secp256r1) + const a = testData.data + const b = testData.recoveryId + const c = testData.r + const d = testData.s + await expect( + getAvmResult( + { appClient, sendParams: { fee: AlgoAmount.Algos(5000) } }, + 'verify_ecdsa_recover_r1', + asUint8Array(a), + b.asNumber(), + asUint8Array(c), + asUint8Array(d), + ), + ).rejects.toThrow('unsupported curve') + + expect(() => op.ecdsaPkRecover(internal.opTypes.Ecdsa.Secp256r1, a, b, c, d)).toThrow('Unsupported ECDSA curve') + }) + }) + + describe('ecdsaPkDecompress', async () => { + it('should be able to decompress k1 public key', async () => { + const v = internal.opTypes.Ecdsa.Secp256k1 + const testData = generateEcdsaTestData(v) + const ecdsa = new 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( + { appClient, sendParams: { fee: AlgoAmount.Algos(3000) } }, + 'verify_ecdsa_decompress_k1', + pubKeyArray, + ) + const result = op.ecdsaPkDecompress(v, pubKeyArray) + + expect(asUint8Array(result[0])).toEqual(new Uint8Array(avmResult[0])) + expect(asUint8Array(result[1])).toEqual(new Uint8Array(avmResult[1])) + }) + }) + + describe('vrfVerify', async () => { + const a = internal.primitives.BytesCls.fromHex('528b9e23d93d0e020a119d7ba213f6beb1c1f3495a217166ecd20f5a70e7c2d7') + const b = internal.primitives.BytesCls.fromHex( + '372a3afb42f55449c94aaa5f274f26543e77e8d8af4babee1a6fbc1c0391aa9e6e0b8d8d7f4ed045d5b517fea8ad3566025ae90d2f29f632e38384b4c4f5b9eb741c6e446b0f540c1b3761d814438b04', + ) + const c = internal.primitives.BytesCls.fromHex('3a2740da7a0788ebb12a52154acbcca1813c128ca0b249e93f8eb6563fee418d') + + it('should throw not available error', async () => { + expect(() => op.vrfVerify(internal.opTypes.VrfVerify.VrfAlgorand, a, b, c)).toThrow('vrfVerify is not available in test context') + }) + + it('should return mocked result', async () => { + const avmResult = await getAvmResult<[Uint8Array, boolean]>( + { appClient, sendParams: { fee: AlgoAmount.Algos(6000) } }, + 'verify_vrf_verify', + asUint8Array(a), + 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(publicOps.VrfVerify.VrfAlgorand, a, b, c) + + expect(asUint8Array(result[0])).toEqual(new Uint8Array(avmResult[0])) + expect(result[1]).toEqual(avmResult[1]) + }) + }) + + describe('EllipticCurve', async () => { + it('should throw not available error', async () => { + expect(() => op.EllipticCurve.add(internal.opTypes.Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( + 'EllipticCurve.add is not available in test context', + ) + expect(() => op.EllipticCurve.mapTo(internal.opTypes.Ec.BN254g2, Bytes(''))).toThrow( + 'EllipticCurve.mapTo is not available in test context', + ) + expect(() => op.EllipticCurve.pairingCheck(internal.opTypes.Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( + 'EllipticCurve.pairingCheck is not available in test context', + ) + expect(() => op.EllipticCurve.scalarMul(internal.opTypes.Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( + 'EllipticCurve.scalarMul is not available in test context', + ) + expect(() => op.EllipticCurve.scalarMulMulti(internal.opTypes.Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( + 'EllipticCurve.scalarMulMulti is not available in test context', + ) + expect(() => op.EllipticCurve.subgroupCheck(internal.opTypes.Ec.BN254g2, Bytes(''))).toThrow( + 'EllipticCurve.subgroupCheck is not available in test context', + ) + }) + }) +}) + +const generateEcdsaTestData = (v: internal.opTypes.Ecdsa) => { + const ecdsa = new 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 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))), + } +} diff --git a/tests/primitives/biguint.spec.ts b/tests/primitives/biguint.spec.ts new file mode 100644 index 0000000..5afce81 --- /dev/null +++ b/tests/primitives/biguint.spec.ts @@ -0,0 +1,652 @@ +import type { biguint } from '@algorandfoundation/algo-ts' +import { BigUint, Bytes, internal, Uint64 } from '@algorandfoundation/algo-ts' +import type { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { describe, expect, it } from 'vitest' +import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' +import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' +import { MAX_UINT512, MAX_UINT64 } from '../../src/constants' + +const asBigUint = (val: bigint | number) => (typeof val === 'bigint' ? BigUint(val) : BigUint(val)) + +describe('BigUint', async () => { + const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + + describe.each(['eq', 'ne', 'lt', 'le', 'gt', 'ge'])('logical operators', async (op) => { + const operator = (function () { + switch (op) { + case 'eq': + return '===' + case 'ne': + return '!==' + case 'lt': + return '<' + case 'le': + return '<=' + case 'gt': + return '>' + case 'ge': + return '>=' + default: + throw new Error(`Unknown operator: ${op}`) + } + })() + const getStubResult = (a: number | bigint | biguint, b: number | bigint | biguint) => { + switch (operator) { + case '===': + return a === b + case '!==': + return a !== b + case '<': + return a < b + case '<=': + return a <= b + case '>': + return a > b + case '>=': + return a >= b + default: + throw new Error(`Unknown operator: ${op}`) + } + } + describe.each([ + [0, 0], + [0, 1], + [0, MAX_UINT512], + [1, 0], + [1, 1], + [256, 512], + [1, MAX_UINT512], + [MAX_UINT512, MAX_UINT512], + ])(`${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()) + + it(`${a} ${operator} ${b}`, async () => { + const avmResult = await getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, bytesB) + let result = getStubResult(bigUintA, bigUintB) + expect(result, `for values: ${a}, ${b}`).toBe(avmResult) + + result = getStubResult(a, bigUintB) + expect(result, `for values: ${a}, ${b}`).toBe(avmResult) + + result = getStubResult(bigUintA, b) + expect(result, `for values: ${a}, ${b}`).toBe(avmResult) + }) + }) + + describe.each([ + [0, 0], + [0, 1], + [0, MAX_UINT512], + [1, 0], + [1, 1], + [256, 512], + [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 bigUintA = BigUint(Bytes(bytesA)) + const bigUintB = BigUint(Bytes(bytesB)) + const paddedBigUintA = BigUint(Bytes(paddedBytesA)) + const paddedBigUintB = BigUint(Bytes(paddedBytesB)) + + it(`${a} ${operator} ${b}`, async () => { + let avmResult = await getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, paddedBytesB) + let result = getStubResult(bigUintA, paddedBigUintB) + expect(result, `for padded b: ${a}, ${b}`).toBe(avmResult) + + avmResult = await getAvmResult({ appClient }, `verify_biguint_${op}`, paddedBytesA, bytesB) + result = getStubResult(paddedBigUintA, bigUintB) + expect(result, `for padded a: ${a}, ${b}`).toBe(avmResult) + + avmResult = await getAvmResult({ appClient }, `verify_biguint_${op}`, paddedBytesA, paddedBytesB) + result = getStubResult(paddedBigUintA, paddedBigUintB) + expect(result, `for padded a and b: ${a}, ${b}`).toBe(avmResult) + }) + }) + + describe.each([ + [0, 0], + [0, 1], + [0, MAX_UINT64], + [1, 0], + [1, 1], + [256, 512], + [MAX_UINT512, MAX_UINT64], + ])(`${operator} with uint64`, async (a, b) => { + const bigUintA = asBigUint(a) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const uintB = typeof b === 'bigint' ? Uint64(b) : Uint64(b) + + it(`${a} ${operator} ${b}`, async () => { + const avmResult = await getAvmResult({ appClient }, `verify_biguint_${op}_uint64`, bytesA, b) + const result = getStubResult(bigUintA, uintB) + expect(result, `for values: ${a}, ${b}`).toBe(avmResult) + }) + }) + + describe.each([ + [MAX_UINT512 + 1n, 1], + [1, MAX_UINT512 + 1n], + [MAX_UINT512 + 1n, MAX_UINT512], + [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 bigUintA = BigUint(Bytes(bytesA)) + const bigUintB = BigUint(Bytes(bytesB)) + + it(`${a} ${operator} ${b}`, async () => { + await expect(getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, bytesB)).rejects.toThrow( + 'math attempted on large byte-array', + ) + expect(() => getStubResult(bigUintA, bigUintB)).toThrow('BigUint over or underflow') + + expect(() => getStubResult(a, bigUintB)).toThrow('BigUint over or underflow') + + expect(() => getStubResult(bigUintA, b)).toThrow('BigUint over or underflow') + }) + }) + }) + + describe.each([ + [0, 0], + [0, MAX_UINT512], + [MAX_UINT512, 0], + [1, 0], + [0, 1], + [1, 1], + [MAX_UINT64, MAX_UINT64], + [1, MAX_UINT512 - 1n], + [MAX_UINT512 - 1n, 1], + ])('addition', async (a, b) => { + it(`${a} + ${b}`, async () => { + const bigUintA = asBigUint(a) + const bigUintB = asBigUint(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_add', bytesA, bytesB))! + const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + let result = bigUintA + bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + + if (typeof a === 'bigint') { + result = a + bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + + if (typeof b === 'bigint') { + result = bigUintA + b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + }) + }) + + describe.each([ + [MAX_UINT512, 1], + [1, MAX_UINT512], + [MAX_UINT512, MAX_UINT512], + ])('addition result overflow', async (a, b) => { + it(`${a} + ${b}`, async () => { + const bigUintA = asBigUint(a) + const bigUintB = asBigUint(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_add', bytesA, bytesB))! + const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + let result = bigUintA + bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + + if (typeof a === 'bigint') { + result = a + bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + + if (typeof b === 'bigint') { + result = bigUintA + b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + }) + }) + + describe.each([ + [MAX_UINT512 + 1n, 1], + [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 bigUintA = BigUint(Bytes(bytesA)) + const bigUintB = BigUint(Bytes(bytesB)) + + it(`${a} + ${b}`, async () => { + await expect(getAvmResultRaw({ appClient }, 'verify_biguint_add', bytesA, bytesB)).rejects.toThrow( + 'math attempted on large byte-array', + ) + expect(() => bigUintA + bigUintB).toThrow('BigUint over or underflow') + + if (typeof a === 'bigint') { + expect(() => a + bigUintB).toThrow('BigUint over or underflow') + } + + if (typeof b === 'bigint') { + expect(() => bigUintA + b).toThrow('BigUint over or underflow') + } + }) + }) + + describe.each([ + [0, 0], + [1, 0], + [1, 1], + [MAX_UINT64, MAX_UINT64], + [MAX_UINT512, 0], + [MAX_UINT512, 1], + [MAX_UINT512, MAX_UINT512], + ])('subtraction', async (a, b) => { + it(`${a} - ${b}`, async () => { + const bigUintA = asBigUint(a) + const bigUintB = asBigUint(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_sub', bytesA, bytesB))! + const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + let result = bigUintA - bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + + if (typeof a === 'bigint') { + result = a - bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + + if (typeof b === 'bigint') { + result = bigUintA - b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + }) + }) + + describe.each([ + [0, 1], + [1, 2], + [MAX_UINT64, MAX_UINT512], + [0, MAX_UINT512], + [1, MAX_UINT512], + ])(`subtraction result underflow`, async (a, b) => { + it(`${a} - ${b}`, async () => { + const bigUintA = asBigUint(a) + const bigUintB = asBigUint(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = internal.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') + + if (typeof a === 'bigint') { + expect(() => a - bigUintB).toThrow('BigUint underflow') + } + + if (typeof b === 'bigint') { + expect(() => bigUintA - b).toThrow('BigUint underflow') + } + }) + }) + + describe.each([ + [MAX_UINT512 + 1n, 1], + [1, MAX_UINT512 + 1n], + [MAX_UINT512 + 1n, MAX_UINT512 + 1n], + ])(`subtraction with overflowing input`, async (a, b) => { + const bytesA = internal.encodingUtil.bigIntToUint8Array(BigInt(a)) + const bytesB = internal.encodingUtil.bigIntToUint8Array(BigInt(b)) + const bigUintA = BigUint(Bytes(bytesA)) + const bigUintB = BigUint(Bytes(bytesB)) + + it(`${a} - ${b}`, async () => { + await expect(getAvmResultRaw({ appClient }, 'verify_biguint_sub', bytesA, bytesB)).rejects.toThrow( + 'math attempted on large byte-array', + ) + expect(() => bigUintA - bigUintB).toThrow('BigUint over or underflow') + + if (typeof a === 'bigint') { + expect(() => a - bigUintB).toThrow('BigUint over or underflow') + } + + if (typeof b === 'bigint') { + expect(() => bigUintA - b).toThrow('BigUint over or underflow') + } + }) + }) + + describe.each([ + [0, 0], + [0, 1], + [0, MAX_UINT512], + [1, MAX_UINT512], + [MAX_UINT64, MAX_UINT64], + [2, 2], + ])(`multiplication`, async (a, b) => { + it(`${a} * ${b}`, async () => { + const bigUintA = asBigUint(a) + const bigUintB = asBigUint(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_mul', bytesA, bytesB))! + const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + let result = bigUintA * bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + + if (typeof a === 'bigint') { + result = a * bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + + if (typeof b === 'bigint') { + result = bigUintA * b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + }) + }) + + describe.each([ + [MAX_UINT512, 2], + [MAX_UINT512, MAX_UINT512], + [MAX_UINT512 / 2n, 3], + ])(`multiplication result overflow`, async (a, b) => { + it(`${a} * ${b}`, async () => { + const bigUintA = asBigUint(a) + const bigUintB = asBigUint(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_mul', bytesA, bytesB))! + const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + let result = bigUintA * bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + + if (typeof a === 'bigint') { + result = a * bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + + if (typeof b === 'bigint') { + result = bigUintA * b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + }) + }) + + describe.each([ + [MAX_UINT512 + 1n, 2], + [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)) + const bigUintA = BigUint(Bytes(bytesA)) + const bigUintB = BigUint(Bytes(bytesB)) + + await expect(getAvmResultRaw({ appClient }, 'verify_biguint_mul', bytesA, bytesB)).rejects.toThrow( + 'math attempted on large byte-array', + ) + expect(() => bigUintA * bigUintB).toThrow('BigUint over or underflow') + + if (typeof a === 'bigint') { + expect(() => a * bigUintB).toThrow('BigUint over or underflow') + } + + if (typeof b === 'bigint') { + expect(() => bigUintA * b).toThrow('BigUint over or underflow') + } + }) + }) + + describe.each([ + [MAX_UINT512, 1], + [MAX_UINT512, 2], + [MAX_UINT512, MAX_UINT512], + [0, MAX_UINT512], + [1, MAX_UINT512], + [3, 2], + ])(`division`, async (a, b) => { + it(`${a} / ${b}`, async () => { + const bigUintA = asBigUint(a) + const bigUintB = asBigUint(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_div', bytesA, bytesB))! + const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + let result = bigUintA / bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + + if (typeof a === 'bigint') { + result = a / bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + + if (typeof b === 'bigint') { + result = bigUintA / b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + }) + }) + + describe.each([0, 1, MAX_UINT512])(`division by zero`, async (a) => { + it(`${a} / 0`, async () => { + const bigUintA = asBigUint(a) + const bigUintB = asBigUint(0) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = internal.encodingUtil.bigIntToUint8Array(0n) + + await expect(getAvmResultRaw({ appClient }, 'verify_biguint_div', bytesA, bytesB)).rejects.toThrow('division by zero') + expect(() => bigUintA / bigUintB).toThrow('Division by zero') + + if (typeof a === 'bigint') { + expect(() => a / bigUintB).toThrow('Division by zero') + } + expect(() => bigUintA / 0n).toThrow('Division by zero') + }) + }) + + describe.each([ + [MAX_UINT512 + 1n, 2], + [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)) + const bigUintA = BigUint(Bytes(bytesA)) + const bigUintB = BigUint(Bytes(bytesB)) + + await expect(getAvmResultRaw({ appClient }, 'verify_biguint_div', bytesA, bytesB)).rejects.toThrow( + 'math attempted on large byte-array', + ) + expect(() => bigUintA / bigUintB).toThrow('BigUint over or underflow') + + if (typeof a === 'bigint') { + expect(() => a / bigUintB).toThrow('BigUint over or underflow') + } + + if (typeof b === 'bigint') { + expect(() => bigUintA / b).toThrow('BigUint over or underflow') + } + }) + }) + + describe.each([ + [MAX_UINT512, 1], + [MAX_UINT512, 2], + [MAX_UINT512, MAX_UINT64], + [0, MAX_UINT512], + [1, MAX_UINT512], + [3, 2], + ])(`modulo`, async (a, b) => { + it(`${a} % ${b}`, async () => { + const bigUintA = asBigUint(a) + const bigUintB = asBigUint(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) + + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_mod', bytesA, bytesB))! + const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + let result = bigUintA % bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + + if (typeof a === 'bigint') { + result = a % bigUintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + + if (typeof b === 'bigint') { + result = bigUintA % b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + }) + }) + + describe.each([0, 1, MAX_UINT512])(`modulo by zero`, async (a) => { + it(`${a} % 0`, async () => { + const bigUintA = asBigUint(a) + const bigUintB = asBigUint(0) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + const bytesB = internal.encodingUtil.bigIntToUint8Array(0n) + + await expect(getAvmResultRaw({ appClient }, 'verify_biguint_mod', bytesA, bytesB)).rejects.toThrow('modulo by zero') + expect(() => bigUintA % bigUintB).toThrow('Division by zero') + + if (typeof a === 'bigint') { + expect(() => a % bigUintB).toThrow('Division by zero') + } + expect(() => bigUintA % 0n).toThrow('Division by zero') + }) + }) + + describe.each([ + [MAX_UINT512 + 1n, 2], + [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)) + const bigUintA = BigUint(Bytes(bytesA)) + const bigUintB = BigUint(Bytes(bytesB)) + + await expect(getAvmResultRaw({ appClient }, 'verify_biguint_mod', bytesA, bytesB)).rejects.toThrow( + 'math attempted on large byte-array', + ) + expect(() => bigUintA % bigUintB).toThrow('BigUint over or underflow') + + if (typeof a === 'bigint') { + expect(() => a % bigUintB).toThrow('BigUint over or underflow') + } + + if (typeof b === 'bigint') { + expect(() => bigUintA % b).toThrow('BigUint over or underflow') + } + }) + }) + + describe.each(['and', 'or', 'xor'])('bitwise operators', async (op) => { + const operator = (function () { + switch (op) { + case 'and': + return '&' + case 'or': + return '|' + case 'xor': + return '^' + default: + throw new Error(`Unknown operator: ${op}`) + } + })() + const getStubResult = (a: bigint | biguint, b: bigint | biguint) => { + switch (operator) { + case '&': + return a & b + case '|': + return a | b + case '^': + return a ^ b + default: + throw new Error(`Unknown operator: ${op}`) + } + } + describe.each([ + [0, 0], + [MAX_UINT512, MAX_UINT512], + [0, MAX_UINT512], + [MAX_UINT512, 0], + [42, MAX_UINT512], + [MAX_UINT512, 42], + ])(`${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()) + + it(`${a} ${operator} ${b}`, async () => { + const avmResult = (await getAvmResultRaw({ appClient }, `verify_biguint_${op}`, bytesA, bytesB))! + const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + let result = getStubResult(bigUintA, bigUintB) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + + if (typeof a === 'bigint') { + result = getStubResult(a, bigUintB) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + + if (typeof b === 'bigint') { + result = getStubResult(bigUintA, b) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + } + }) + }) + }) + + describe.each([MAX_UINT512 + 1n, MAX_UINT512 * 2n])('value too big', (a) => { + it(`${a}`, () => { + const bigUintA = asBigUint(a) + expect(() => bigUintA === a).toThrow('BigUint over or underflow') + }) + }) + + describe.each([-1, -MAX_UINT512, -MAX_UINT512 * 2n])('value too small', (a) => { + it(`${a}`, () => { + const bigUintA = asBigUint(a) + expect(() => bigUintA === asBigUint(a)).toThrow('BigUint over or underflow') + }) + }) + + describe.each([ + [true, 1n], + [false, 0n], + [0, 0n], + [1, 1n], + [42, 42n], + [0n, 0n], + [1n, 1n], + [42n, 42n], + [MAX_UINT512, MAX_UINT512], + [MAX_UINT512 * 2n, MAX_UINT512 * 2n], + [Bytes('hello'), 448378203247n], + ])('fromCompat', async (a, b) => { + it(`${a}`, async () => { + const result = internal.primitives.BigUintCls.fromCompat(a) + expect(result.valueOf(), `for value: ${a}`).toBe(b) + }) + }) +}) diff --git a/tests/primitives/bytes.spec.ts b/tests/primitives/bytes.spec.ts new file mode 100644 index 0000000..3b3721b --- /dev/null +++ b/tests/primitives/bytes.spec.ts @@ -0,0 +1,190 @@ +import { bytes, Bytes, internal } from '@algorandfoundation/algo-ts' +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { describe, expect, it } from 'vitest' +import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' +import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' +import { asUint8Array, getSha256Hash, padUint8Array } from '../util' +import { MAX_BYTES_SIZE } from '../../src/constants' + +describe('Bytes', async () => { + const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + + describe.each([ + ['', '', 0, 0], + ['1', '', 0, 0], + ['', '1', 0, 0], + ['1', '1', 0, 0], + ['', '0', 0, MAX_BYTES_SIZE - 1], + ['0', '', MAX_BYTES_SIZE - 1, 0], + ['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) + const avmResult = (await getAvmResultRaw({ appClient }, `verify_bytes_add`, uint8ArrayA, uint8ArrayB, padASize, padBSize))! + + const bytesA = Bytes(padUint8Array(uint8ArrayA, padASize)) + const bytesB = Bytes(padUint8Array(uint8ArrayB, padBSize)) + const result = bytesA.concat(bytesB) + const resultUint8Array = asUint8Array(result) + const resultHash = getSha256Hash(resultUint8Array) + expect(resultHash, `for values: ${a}, ${b}`).toEqual(avmResult) + }) + }) + + describe.each([ + ['', '', 1, MAX_BYTES_SIZE], + ['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) + + await expect(getAvmResultRaw({ appClient }, `verify_bytes_add`, uint8ArrayA, uint8ArrayB, padASize, padBSize)).rejects.toThrow( + /concat produced a too big \(\d+\) byte-array/, + ) + + const bytesA = Bytes(padUint8Array(uint8ArrayA, padASize)) + const bytesB = Bytes(padUint8Array(uint8ArrayB, padBSize)) + expect(() => bytesA.concat(bytesB)).toThrow(/Bytes length \d+ exceeds maximum length/) + }) + }) + + describe.each(['and', 'or', 'xor'])('bitwise operators', async (op) => { + const getStubResult = (a: bytes, b: bytes) => { + switch (op) { + case 'and': + return a.bitwiseAnd(b) + case 'or': + return a.bitwiseOr(b) + case 'xor': + return a.bitwiseXor(b) + default: + throw new Error(`Unknown operator: ${op}`) + } + } + describe.each([ + ['0', '0'], + ['001', '11'], + ['100', '11'], + ['00', '111'], + ['11', '001'], + ['', '11'], + ])(`bitwise ${op}`, async (a, b) => { + it(`${a} bitwise ${op} ${b}`, async () => { + const bytesA = Bytes(a) + const bytesB = Bytes(b) + + const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) + const uint8ArrayB = internal.encodingUtil.utf8ToUint8Array(b) + const avmResult = (await getAvmResultRaw({ appClient }, `verify_bytes_${op}`, uint8ArrayA, uint8ArrayB))! + const result = getStubResult(bytesA, bytesB) + const resultUint8Array = asUint8Array(result) + expect(resultUint8Array, `for values: ${a}, ${b}`).toEqual(avmResult) + }) + }) + }) + + describe.each([ + ['0', 0], + ['1', 0], + ['1010', 0], + ['11100', MAX_BYTES_SIZE - 5], + ['', MAX_BYTES_SIZE], + ])('bitwise invert', async (a, padSize) => { + it(`~${a}`, async () => { + const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) + const avmResult = (await getAvmResultRaw({ appClient }, `verify_bytes_not`, uint8ArrayA, padSize))! + + const bytesA = Bytes(padUint8Array(uint8ArrayA, padSize)) + const result = bytesA.bitwiseInvert() + const resultUint8Array = asUint8Array(result) + const resultHash = getSha256Hash(resultUint8Array) + + expect(resultHash, `for value: ${a}`).toEqual(avmResult) + }) + }) + + describe.each([ + ['0', '0'], + ['', ''], + ['11', '11'], + ['011', '11'], + ['11', '001'], + ['', '00'], + ])('equals', async (a, b) => { + it(`${a} equals ${b}`, async () => { + const bytesA = Bytes(a) + const bytesB = Bytes(b) + const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) + const uint8ArrayB = internal.encodingUtil.utf8ToUint8Array(b) + + const avmResult = await getAvmResult({ appClient }, `verify_bytes_eq`, uint8ArrayA, uint8ArrayB) + const result = bytesA.equals(bytesB) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) + }) + }) + + describe.each([ + ['0', '0'], + ['', ''], + ['11', '11'], + ['011', '11'], + ['11', '001'], + ['', '00'], + ])('not equals', async (a, b) => { + it(`${a} not equals ${b}`, async () => { + const bytesA = Bytes(a) + const bytesB = Bytes(b) + const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) + const uint8ArrayB = internal.encodingUtil.utf8ToUint8Array(b) + + const avmResult = await getAvmResult({ appClient }, `verify_bytes_ne`, uint8ArrayA, uint8ArrayB) + const result = !bytesA.equals(bytesB) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) + }) + }) + + describe('from encoded string', () => { + it('hex', () => { + const hex = 'FF' + const bytes = Bytes.fromHex(hex) + const resultUint8Array = asUint8Array(bytes) + expect(resultUint8Array).toEqual(Uint8Array.from([0xff])) + }) + + it('base64', () => { + const base64 = '/w==' + const bytes = Bytes.fromBase64(base64) + const resultUint8Array = asUint8Array(bytes) + expect(resultUint8Array).toEqual(Uint8Array.from([0xff])) + }) + + it('base32', () => { + const base32 = '74======' + const bytes = Bytes.fromBase32(base32) + const resultUint8Array = asUint8Array(bytes) + expect(resultUint8Array).toEqual(Uint8Array.from([0xff])) + }) + }) + + describe.each([MAX_BYTES_SIZE + 1, MAX_BYTES_SIZE * 2])('value overflows', (size) => { + it(`${size} bytes`, () => { + const a = new Uint8Array(size).fill(0) + expect(() => Bytes(a)).toThrow(/Bytes length \d+ exceeds maximum length/) + }) + }) + + describe.each([ + [undefined, new Uint8Array(0)], + ['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) + expect(result.asUint8Array()).toEqual(b) + }) + }) +}) diff --git a/tests/primitives/uint64.spec.ts b/tests/primitives/uint64.spec.ts new file mode 100644 index 0000000..6711294 --- /dev/null +++ b/tests/primitives/uint64.spec.ts @@ -0,0 +1,515 @@ +import { internal, uint64, Uint64 } from '@algorandfoundation/algo-ts' +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { describe, expect, it } from 'vitest' +import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' +import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' + +const MAX_UINT64 = 2n ** 64n - 1n +const asUint64 = (val: bigint | number) => (typeof val === 'bigint' ? Uint64(val) : Uint64(val)) + +describe('Unit64', async () => { + const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + + describe.each(['eq', 'ne', 'lt', 'le', 'gt', 'ge'])('logical operators', async (op) => { + const operator = (function () { + switch (op) { + case 'eq': + return '===' + case 'ne': + return '!==' + case 'lt': + return '<' + case 'le': + return '<=' + case 'gt': + return '>' + case 'ge': + return '>=' + default: + throw new Error(`Unknown operator: ${op}`) + } + })() + describe.each([ + [0, 0], + [0, 1], + [0, MAX_UINT64], + [1, 0], + [1, 1], + [1, MAX_UINT64], + [13, 42], + [MAX_UINT64, MAX_UINT64], + ])(`${operator}`, async (a, b) => { + const uintA = asUint64(a) + const uintB = asUint64(b) + + const getStubResult = (a: number | bigint | uint64, b: number | bigint | uint64) => { + switch (operator) { + case '===': + return a === b + case '!==': + return a !== b + case '<': + return a < b + case '<=': + return a <= b + case '>': + return a > b + case '>=': + return a >= b + default: + throw new Error(`Unknown operator: ${op}`) + } + } + it(`${a} ${operator} ${b}`, async () => { + const avmResult = await getAvmResult({ appClient }, `verify_uint64_${op}`, a, b) + let result = getStubResult(uintA, uintB) + expect(result, `for values: ${a}, ${b}`).toBe(avmResult) + + result = getStubResult(a, uintB) + expect(result, `for values: ${a}, ${b}`).toBe(avmResult) + + result = getStubResult(uintA, b) + expect(result, `for values: ${a}, ${b}`).toBe(avmResult) + }) + }) + }) + + describe.each([ + [0, 0], + [0, MAX_UINT64], + [MAX_UINT64, 0], + [1, 0], + [0, 1], + [1, 1], + [13, 42], + [1, MAX_UINT64 - 1n], + [MAX_UINT64 - 1n, 1], + ])('addition', async (a, b) => { + it(`${a} + ${b}`, async () => { + 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) + + if (typeof a === 'number') { + result = a + asUint64(b) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + + if (typeof b === 'number') { + result = asUint64(a) + b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + }) + }) + + describe.each([ + [1, MAX_UINT64], + [MAX_UINT64, 1], + [MAX_UINT64, MAX_UINT64], + ])('addition overflow', async (a, b) => { + it(`${a} + ${b}`, async () => { + await expect(getAvmResult({ appClient }, 'verify_uint64_add', a, b)).rejects.toThrow('+ overflowed') + + expect(() => asUint64(a) + asUint64(b)).toThrow('Uint64 over or underflow') + + if (typeof a === 'number') { + expect(() => a + asUint64(b)).toThrow('Uint64 over or underflow') + } + + if (typeof b === 'number') { + expect(() => asUint64(a) + b).toThrow('Uint64 over or underflow') + } + }) + }) + + describe.each([ + [0, 0], + [1, 0], + [1, 1], + [42, 13], + [MAX_UINT64, 0], + [MAX_UINT64, 1], + [MAX_UINT64, MAX_UINT64], + ])('subtraction', async (a, b) => { + it(`${a} - ${b}`, async () => { + 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) + + if (typeof a === 'number') { + result = a - asUint64(b) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + + if (typeof b === 'number') { + result = asUint64(a) - b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + }) + }) + + describe.each([ + [0, 1], + [1, 2], + [13, 42], + [0, MAX_UINT64], + [1, MAX_UINT64], + ])('subtraction underflow', async (a, b) => { + it(`${a} - ${b}`, async () => { + await expect(getAvmResult({ appClient }, 'verify_uint64_sub', a, b)).rejects.toThrow('- would result negative') + + expect(() => asUint64(a) - asUint64(b)).toThrow('Uint64 over or underflow') + + if (typeof a === 'number') { + expect(() => a - asUint64(b)).toThrow('Uint64 over or underflow') + } + + if (typeof b === 'number') { + expect(() => asUint64(a) - b).toThrow('Uint64 over or underflow') + } + }) + }) + + describe.each([ + [0, 0], + [0, 1], + [42, 13], + [MAX_UINT64, 0], + [MAX_UINT64, 1], + ])('multiplication', async (a, b) => { + it(`${a} * ${b}`, async () => { + 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) + + if (typeof a === 'number') { + result = a * asUint64(b) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + + if (typeof b === 'number') { + result = asUint64(a) * b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + }) + }) + + describe.each([ + [MAX_UINT64, 2], + [MAX_UINT64, MAX_UINT64], + [MAX_UINT64 / 2n, 3], + ])('multiplication overflow', async (a, b) => { + it(`${a} * ${b}`, async () => { + await expect(getAvmResult({ appClient }, 'verify_uint64_mul', a, b)).rejects.toThrow('* overflowed') + + expect(() => asUint64(a) * asUint64(b)).toThrow('Uint64 over or underflow') + + if (typeof a === 'number') { + expect(() => a * asUint64(b)).toThrow('Uint64 over or underflow') + } + + if (typeof b === 'number') { + expect(() => asUint64(a) * b).toThrow('Uint64 over or underflow') + } + }) + }) + + describe.each([ + [0, 1], + [1, 1], + [42, 13], + [0, MAX_UINT64], + [1, MAX_UINT64], + [MAX_UINT64, MAX_UINT64], + ])('division', async (a, b) => { + it(`${a} / ${b}`, async () => { + 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) + + if (typeof a === 'number') { + result = a / asUint64(b) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + + if (typeof b === 'number') { + result = asUint64(a) / b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + }) + }) + + describe.each([ + [0, 0], + [1, 0], + [MAX_UINT64, 0], + ])('division by zero', async (a, b) => { + it(`${a} / ${b}`, async () => { + await expect(getAvmResult({ appClient }, 'verify_uint64_div', a, b)).rejects.toThrow('/ 0') + + expect(() => asUint64(a) / asUint64(b)).toThrow('Division by zero') + + if (typeof a === 'number') { + expect(() => a / asUint64(b)).toThrow('Division by zero') + } + + expect(() => asUint64(a) / b).toThrow('Division by zero') + }) + }) + + describe.each([ + [0, 1], + [1, 1], + [42, 13], + [0, MAX_UINT64], + [1, MAX_UINT64], + [MAX_UINT64, MAX_UINT64], + ])('modulo', async (a, b) => { + it(`${a} % ${b}`, async () => { + 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) + + if (typeof a === 'number') { + result = a % asUint64(b) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + + if (typeof b === 'number') { + result = asUint64(a) % b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + }) + }) + + describe.each([ + [0, 0], + [1, 0], + [MAX_UINT64, 0], + ])('modulo by zero', async (a, b) => { + it(`${a} % ${b}`, async () => { + await expect(getAvmResult({ appClient }, 'verify_uint64_mod', a, b)).rejects.toThrow('% 0') + + expect(() => asUint64(a) % asUint64(b)).toThrow('Division by zero') + + if (typeof a === 'number') { + expect(() => a % asUint64(b)).toThrow('Division by zero') + } + + expect(() => asUint64(a) % b).toThrow('Division by zero') + }) + }) + + describe.each([ + [0, 1], + [1, 1], + [1, 0], + [0, MAX_UINT64], + [1, MAX_UINT64], + [MAX_UINT64, 0], + [MAX_UINT64, 1], + [2 ** 31, 2], + ])('pow', async (a, b) => { + it(`${a} ** ${b}`, async () => { + 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) + + if (typeof a === 'number') { + result = a ** asUint64(b) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + + if (typeof b === 'number') { + result = asUint64(a) ** b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + }) + }) + + describe('pow undefined', async () => { + it('0 ** 0', async () => { + const a = 0, + b = 0 + await expect(getAvmResult({ appClient }, 'verify_uint64_pow', a, b)).rejects.toThrow('0^0 is undefined') + expect(() => asUint64(a) ** asUint64(b)).toThrow('0 ** 0 is undefined') + }) + }) + + describe.each([ + [MAX_UINT64, 2], + [2, 64], + [2 ** 32, 32], + ])('pow overflow', async (a, b) => { + it(`${a} ** ${b}`, async () => { + await expect(getAvmResult({ appClient }, 'verify_uint64_pow', a, b)).rejects.toThrow(/\d+\^\d+ overflow/) + + expect(() => asUint64(a) ** asUint64(b)).toThrow('Uint64 over or underflow') + + if (typeof a === 'number') { + expect(() => a ** asUint64(b)).toThrow('Uint64 over or underflow') + } + + if (typeof b === 'number') { + expect(() => asUint64(a) ** b).toThrow('Uint64 over or underflow') + } + }) + }) + + describe.each(['and', 'or', 'xor'])('bitwise operators', async (op) => { + describe.each([ + [0, 0], + [MAX_UINT64, MAX_UINT64], + [0, MAX_UINT64], + [MAX_UINT64, 0], + [42, MAX_UINT64], + [MAX_UINT64, 42], + ])(`${op}`, async (a, b) => { + const uintA = asUint64(a) + const uintB = asUint64(b) + const operator = (function () { + switch (op) { + case 'and': + return '&' + case 'or': + return '|' + case 'xor': + return '^' + default: + throw new Error(`Unknown operator: ${op}`) + } + })() + const getStubResult = (a: number | uint64, b: number | uint64) => { + switch (op) { + case 'and': + return a & b + case 'or': + return a | b + case 'xor': + return a ^ b + default: + throw new Error(`Unknown operator: ${op}`) + } + } + it(`${a} ${operator} ${b}`, async () => { + const avmResult = await getAvmResult({ appClient }, `verify_uint64_${op}`, a, b) + let result = getStubResult(uintA, uintB) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + + if (typeof a === 'number') { + result = getStubResult(a, uintB) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + + if (typeof b === 'number') { + result = getStubResult(uintA, b) + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + }) + }) + }) + + describe.each([0, 1, 42, MAX_UINT64])('bitwise invert', async (a) => { + it(`~${a}`, async () => { + const avmResult = await getAvmResult({ appClient }, 'verify_uint64_not', a) + const result = ~asUint64(a) + expect(result.valueOf(), `for value: ${a}`).toBe(avmResult) + }) + }) + + describe.each([ + [0, 0], + [1, 0], + [1, 1], + [1, 63], + [42, 42], + [MAX_UINT64, 0], + [MAX_UINT64, 1], + [MAX_UINT64, 63], + ])('shift operations', async (a, b) => { + const uintA = asUint64(a) + const uintB = asUint64(b) + it(`${a} << ${b}`, async () => { + const avmResult = await getAvmResult({ appClient }, 'verify_uint64_lshift', a, b) + let result = uintA << uintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + + if (typeof a === 'number') { + result = a << uintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + + if (typeof b === 'number') { + result = uintA << b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + }) + + it(`${a} >> ${b}`, async () => { + const avmResult = await getAvmResult({ appClient }, 'verify_uint64_rshift', a, b) + let result = uintA >> uintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + + if (typeof a === 'number') { + result = a >> uintB + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + + if (typeof b === 'number') { + result = uintA >> b + expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResult) + } + }) + }) + + describe('invalid shift operations', async () => { + const a = 0, + b = 64 + const uintA = asUint64(a) + const uintB = asUint64(b) + it('0 << 64', async () => { + 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') + expect(() => uintA << b).toThrow('expected shift <= 63') + expect(() => Uint64(MAX_UINT64 + 1n) << Uint64(1n)).toThrow('Uint64 over or underflow') + }) + + it('0 >> 64', async () => { + 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') + expect(() => uintA >> b).toThrow('expected shift <= 63') + expect(() => Uint64(MAX_UINT64 + 1n) >> Uint64(1n)).toThrow('Uint64 over or underflow') + }) + }) + + describe.each([MAX_UINT64 + 1n, MAX_UINT64 * 2n])('value too big', (a) => { + it(`${a}`, () => { + expect(() => Uint64(a)).toThrow('Uint64 over or underflow') + }) + }) + + describe.each([-1, -MAX_UINT64, -MAX_UINT64 * 2n])('value too small', (a) => { + it(`${a}`, () => { + expect(() => asUint64(a)).toThrow('Uint64 over or underflow') + }) + }) + + describe.each([ + [true, 1n], + [false, 0n], + [0, 0n], + [1, 1n], + [42, 42n], + [0n, 0n], + [1n, 1n], + [42n, 42n], + [MAX_UINT64, MAX_UINT64], + ])('fromCompat', async (a, b) => { + it(`${a}`, async () => { + const result = internal.primitives.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 new file mode 100644 index 0000000..27770bc --- /dev/null +++ b/tests/pure-op-codes.spec.ts @@ -0,0 +1,1014 @@ +import { BigUint, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { afterEach, describe, expect, it, test } from 'vitest' +import { TestExecutionContext } from '../src' +import { MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT64 } from '../src/constants' +import * as op from '../src/impl/pure' +import { asBigUintCls, asBytesCls } from '../src/util' +import appSpecJson from './artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json' +import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from './avm-invoker' +import { asUint8Array, base64Encode, base64UrlEncode, getPaddedUint8Array, getSha256Hash, intToBytes } from './util' + +const avmIntArgOverflowError = 'is not a non-negative int or too big to fit in size' +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 ctx = new TestExecutionContext() + + afterEach(async () => { + ctx.reset() + }) + + describe('addw', async () => { + test.each([ + [0, 0], + [0, MAX_UINT64], + [MAX_UINT64, 0], + [1, 0], + [0, 1], + [100, 42], + [1, MAX_UINT64 - 1n], + [MAX_UINT64 - 1n, 1], + [100, MAX_UINT64], + [MAX_UINT64, MAX_UINT64], + ])('should add two uint64 values', async (a, b) => { + 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([ + [1, MAX_UINT64 + 1n], + [MAX_UINT64 + 1n, 1], + [0, MAX_UINT512], + [MAX_UINT512 * 2n, 0], + ])('should throw error when input overflows', async (a, b) => { + await expect(getAvmResultRaw({ appClient }, 'verify_addw', a, b)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.addw(a, b)).toThrow('Uint64 over or underflow') + }) + }) + + describe('base64Decode', async () => { + test.each([ + base64Encode(''), + base64Encode('abc'), + base64Encode('hello, world.'), + base64Encode('0123.'), + base64Encode(new Uint8Array([0xff])), + base64Encode(new Uint8Array(Array(256).fill(0x00).concat([0xff]))), + ])('should decode standard base64 string', async (a) => { + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_base64_decode_standard', asUint8Array(a)))! + const result = op.base64Decode(internal.opTypes.Base64.StdEncoding, a) + expect(asBytesCls(result).asUint8Array()).toEqual(avmResult) + }) + + test.each([Bytes(new Uint8Array(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) => { + await expect(getAvmResultRaw({ appClient }, 'verify_base64_decode_standard', asUint8Array(a))).rejects.toThrow( + 'illegal base64 data at input byte 0', + ) + expect(() => op.base64Decode(internal.opTypes.Base64.StdEncoding, a)).toThrow('illegal base64 data') + }, + ) + + test.each([ + base64UrlEncode(''), + base64UrlEncode('abc'), + base64UrlEncode('hello, world.'), + base64UrlEncode('0123.'), + base64UrlEncode(new Uint8Array([0xff])), + base64UrlEncode(new Uint8Array(Array(256).fill(0x00).concat([0xff]))), + ])('should decode base64url string', async (a) => { + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_base64_decode_url', asUint8Array(a)))! + const result = op.base64Decode(internal.opTypes.Base64.URLEncoding, a) + expect(asBytesCls(result).asUint8Array()).toEqual(avmResult) + }) + + test.each([Bytes(new Uint8Array(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) => { + await expect(getAvmResultRaw({ appClient }, 'verify_base64_decode_url', asUint8Array(a))).rejects.toThrow('illegal base64 data') + expect(() => op.base64Decode(internal.opTypes.Base64.URLEncoding, a)).toThrow('illegal base64 data') + }, + ) + }) + + 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], + [Bytes(new Uint8Array(Array(8).fill(0x00).concat(Array(4).fill(0x0f)))), 0], + [Bytes(new Uint8Array([0x0f])), MAX_BYTES_SIZE - 1], + [Bytes(new Uint8Array()), 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 = getPaddedUint8Array(padSize, a) + const result = op.bitLength(paddedA) + expect(result.valueOf()).toBe(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.valueOf()).toBe(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 over or underflow') + }) + }) + + 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 getAvmResultRaw({ appClient }, 'verify_bsqrt', uint8ArrayA))! + + const result = op.bsqrt(a) + const bytesResult = asBigUintCls(result).toBytes() + expect(bytesResult.asUint8Array()).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 over or underflow') + }) + }) + + describe('btoi', async () => { + test.each([ + Bytes(internal.encodingUtil.bigIntToUint8Array(0n)), + Bytes(internal.encodingUtil.bigIntToUint8Array(1n)), + Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT64)), + Bytes(new Uint8Array(Array(4).fill(0x00).concat(Array(4).fill(0x0f)))), + ])('should convert bytes to uint64', async (a) => { + const avmResult = await getAvmResult({ appClient }, 'verify_btoi', asUint8Array(a)) + const result = op.btoi(a) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512)), + Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512 * MAX_UINT512, 128)), + Bytes(new Uint8Array(Array(5).fill(0x00).concat(Array(4).fill(0x0f)))), + ])('should throw error when input overflows', async (a) => { + 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) + }) + }) + + describe('bzero', async () => { + test.each([0, 1, 42, MAX_BYTES_SIZE])('should retrun a zero filled bytes value of the given size', async (a) => { + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_bzero', a))! + const result = op.bzero(a) + const resultHash = 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.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 over or underflow') + }) + }) + + describe('concat', async () => { + test.each([ + ['', '', 0, 0], + ['1', '', 0, 0], + ['', '1', 0, 0], + ['1', '1', 0, 0], + ['', '0', 0, MAX_BYTES_SIZE - 1], + ['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) => { + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_concat', asUint8Array(a), asUint8Array(b), padASize, padBSize))! + + const paddedA = getPaddedUint8Array(padASize, a) + const paddedB = getPaddedUint8Array(padBSize, b) + + const result = op.concat(paddedA, paddedB) + const resultHash = getSha256Hash(asUint8Array(result)) + expect(resultHash).toEqual(avmResult) + }) + + test.each([ + ['1', '0', MAX_BYTES_SIZE, 0], + ['1', '1', MAX_BYTES_SIZE, MAX_BYTES_SIZE], + ['1', '0', 0, MAX_BYTES_SIZE], + ])('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 = getPaddedUint8Array(padASize, a) + const paddedB = getPaddedUint8Array(padBSize, b) + + expect(() => op.concat(paddedA, paddedB)).toThrow(/Bytes length \d+ exceeds maximum length/) + }) + }) + + describe('divmodw', async () => { + test.each([ + [0, 1, 0, 1], + [100, 42, 100, 42], + [42, 100, 42, 100], + [0, MAX_UINT64, 0, MAX_UINT64], + [MAX_UINT64, 1, MAX_UINT64, 1], + [1, MAX_UINT64, 1, MAX_UINT64], + [MAX_UINT64 - 1n, 1, MAX_UINT64 - 1n, 1], + [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) => { + 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]) + expect(result[1].valueOf()).toBe(avmResult[1]) + expect(result[2].valueOf()).toBe(avmResult[2]) + expect(result[3].valueOf()).toBe(avmResult[3]) + }) + + test.each([ + [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) => { + await expect(getAvmResultRaw({ appClient }, 'verify_divmodw', a, b, c, d)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.divmodw(a, b, c, d)).toThrow('Uint64 over or underflow') + }) + + test.each([ + [0, 1], + [100, 42], + [42, 100], + [0, MAX_UINT64], + [MAX_UINT64, 1], + [1, MAX_UINT64], + [MAX_UINT64 - 1n, 1], + [1, MAX_UINT64 - 1n], + [100, MAX_UINT64], + [MAX_UINT64, MAX_UINT64], + ])('should throw error when dividing by zero', async (a, b) => { + 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([ + [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) => { + const avmResult = await getAvmResult({ appClient }, 'verify_divw', a, b, c) + const result = op.divw(a, b, c) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + [0, 1], + [100, 42], + [42, 100], + [0, MAX_UINT64], + [MAX_UINT64, 1], + [1, MAX_UINT64], + [MAX_UINT64 - 1n, 1], + [1, MAX_UINT64 - 1n], + [100, MAX_UINT64], + [MAX_UINT64, MAX_UINT64], + ])('should throw error when dividing by zero', async (a, b) => { + 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([ + [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) => { + await expect(getAvmResultRaw({ appClient }, 'verify_divw', a, b, c)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.divw(a, b, c)).toThrow('Uint64 over or underflow') + }) + + test.each([ + [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) => { + await expect(getAvmResultRaw({ appClient }, 'verify_divw', a, b, c)).rejects.toThrow('divw overflow') + expect(() => op.divw(a, b, c)).toThrow('Uint64 over or underflow') + }) + }) + + describe('exp', async () => { + test.each([ + [0, 1], + [1, 0], + [42, 11], + [sqrtMaxUint64, 2], + [1, MAX_UINT64], + ])('should calculate the exponentiation result', async (a, b) => { + const avmResult = await getAvmResult({ appClient }, 'verify_exp', a, b) + const result = op.exp(a, b) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + [100, 42], + [MAX_UINT64, 2], + [2, 64], + ])('should throw error when result overflows', async (a, b) => { + await expect(getAvmResultRaw({ appClient }, 'verify_exp', a, b)).rejects.toThrow('overflow') + expect(() => op.exp(a, b)).toThrow('Uint64 over or underflow') + }) + + test.each([ + [1, MAX_UINT64 + 1n], + [MAX_UINT64 + 1n, 1], + [0, MAX_UINT512], + [MAX_UINT512 * 2n, 1], + ])('should throw error when input overflows', async (a, b) => { + await expect(getAvmResultRaw({ appClient }, 'verify_exp', a, b)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.exp(a, b)).toThrow('Uint64 over or underflow') + }) + + it('0 ** 0 is not supported', async () => { + 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([ + [0, 1], + [1, 0], + [42, 11], + [sqrtMaxUint64, 4], + [2, 127], + ])('should calculate the exponentiation result', async (a, b) => { + 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([ + [100, 42], + [MAX_UINT64, 3], + [2, 128], + ])('should throw error when result overflows', async (a, b) => { + await expect(getAvmResultRaw({ appClient }, 'verify_expw', a, b)).rejects.toThrow('overflow') + expect(() => op.expw(a, b)).toThrow('Uint64 over or underflow') + }) + + test.each([ + [1, MAX_UINT64 + 1n], + [MAX_UINT64 + 1n, 1], + [0, MAX_UINT512], + [MAX_UINT512 * 2n, 1], + ])(`should throw error when input overflows`, async (a, b) => { + await expect(getAvmResultRaw({ appClient }, 'verify_expw', a, b)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.expw(a, b)).toThrow('Uint64 over or underflow') + }) + + it('0 ** 0 is not supported', async () => { + 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([ + [0, 0], + [0, 1], + [0, 2], + [11, 1], + [12, 0], + [8, 4], + [256, 0], + [256, 3], + ])(`should extract bytes from the input`, async (b, c) => { + const a = 'hello, world'.repeat(30) + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_extract', asUint8Array(a), b, c))! + let result = op.extract(a, Uint64(b), Uint64(c)) + expect(asUint8Array(result)).toEqual(avmResult) + + if (c) { + result = op.extract(a, b, c) + expect(asUint8Array(result)).toEqual(avmResult) + } + }) + + test.each(['hello, world', 'hi'])('should work to extract bytes from 2 to end', async (a) => { + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_extract_from_2', asUint8Array(a)))! + const result = op.extract(a, 2, 0) + expect(asUint8Array(result)).toEqual(avmResult) + }) + + test.each([ + [1, MAX_UINT64 + 1n], + [MAX_UINT64 + 1n, 1], + [0, MAX_UINT512], + [MAX_UINT512 * 2n, 1], + ])(`should throw error when input overflows`, async (b, c) => { + 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 over or underflow') + }) + + test.each([ + [0, 13], + [13, 0], + [11, 2], + [8, 5], + ])('should throw error when input is invalid', async (b, c) => { + 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) + }) + }) + + describe('extractUint16', async () => { + test.each([ + [intToBytes(256), 0], + [getPaddedUint8Array(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) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + [getPaddedUint8Array(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 over or underflow') + }) + + test.each([ + [intToBytes(0), 0], + [intToBytes(0), 1], + [intToBytes(256), 1], + [getPaddedUint8Array(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) + }) + }) + + describe('extractUint32', async () => { + test.each([ + [new Uint8Array([0x0f, 0x66, 0x66, 0x66]), 0], + [getPaddedUint8Array(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) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + [getPaddedUint8Array(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 over or underflow') + }) + + test.each([ + [intToBytes(0), 0], + [intToBytes(0), 1], + [intToBytes(256), 1], + [getPaddedUint8Array(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) + }) + }) + + describe('extractUint64', async () => { + test.each([ + [new Uint8Array([0x0f, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66]), 0], + [getPaddedUint8Array(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) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + [getPaddedUint8Array(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 over or underflow') + }) + + test.each([ + [intToBytes(0), 0], + [intToBytes(0), 1], + [intToBytes(256), 1], + [getPaddedUint8Array(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) + }) + }) + + describe('getBit', async () => { + test.each([ + [new Uint8Array([0x00]), 0], + [getPaddedUint8Array(2, intToBytes(256)), 3], + [getPaddedUint8Array(2, intToBytes(256)), 0], + [getPaddedUint8Array(2, intToBytes(256)), 11], + [getPaddedUint8Array(2, intToBytes(65535)), 31], + [getPaddedUint8Array(2, intToBytes(65535)), 24], + [intToBytes(MAX_UINT64), 63], + [intToBytes(MAX_UINT64 - 1n), 63], + [intToBytes(MAX_UINT512), 511], + [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) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + [new Uint8Array([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( + 'getbit index beyond byteslice', + ) + expect(() => op.getBit(a, b)).toThrow(/getBit index \d+ is beyond length/) + }) + + test.each([ + [0, 0], + [0, 3], + [0, 10], + [256, 3], + [256, 0], + [256, 11], + [65535, 15], + [65535, 7], + [65535, 63], + [MAX_UINT64, 63], + [MAX_UINT64 - 1n, 63], + [MAX_UINT64, 0], + ])(`should get the bit at the given index of uint64 value`, async (a, b) => { + const avmResult = await getAvmResult({ appClient }, 'verify_getbit_uint64', a, b) + const result = op.getBit(a, b) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + [MAX_UINT64, 64], + [MAX_UINT64 - 1n, 64], + ])(`should throw error when index out of bound of uint64 value`, async (a, b) => { + 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([ + [new Uint8Array([0x00]), 0], + [getPaddedUint8Array(2, intToBytes(256)), 3], + [getPaddedUint8Array(2, intToBytes(256)), 0], + [getPaddedUint8Array(2, intToBytes(256)), 1], + [getPaddedUint8Array(2, intToBytes(65530)), 3], + [intToBytes(MAX_UINT64), 7], + [intToBytes(MAX_UINT64 - 1n), 0], + [intToBytes(MAX_UINT64 - 1n), 7], + [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) + expect(result.valueOf()).toEqual(avmResult) + }) + + test.each([ + [new Uint8Array([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( + 'getbyte index beyond array length', + ) + expect(() => op.getByte(a, b)).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 getAvmResultRaw({ appClient }, 'verify_itob', a))! + const result = op.itob(a) + expect(asUint8Array(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 over or underflow') + }) + }) + + describe('mulw', async () => { + test.each([ + [0, 0], + [1, 0], + [0, 1], + [100, 42], + [1, MAX_UINT64 - 1n], + [MAX_UINT64 - 1n, 1], + [100, MAX_UINT64], + [MAX_UINT64, MAX_UINT64], + ])(`should calculate the multiplication result`, async (a, b) => { + 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([ + [1, MAX_UINT64 + 1n], + [MAX_UINT64 + 1n, 1], + [0, MAX_UINT512], + [MAX_UINT512 * 2n, 0], + ])(`should throw error when input overflows`, async (a, b) => { + await expect(getAvmResult({ appClient }, 'verify_mulw', a, b)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.mulw(a, b)).toThrow('Uint64 over or underflow') + }) + }) + + describe('replace', async () => { + test.each([ + ['hello, world.', 5, '!!'], + ['hello, world.', 5, ''], + ['hello, world.', 5, ', there.'], + ['hello, world.', 12, '!'], + ['hello, world.', 12, ''], + ['hello, world.', 0, 'H'], + ['', 0, ''], + ])(`should replace bytes in the input`, async (a, b, c) => { + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_replace', asUint8Array(a), b, asUint8Array(c)))! + const result = op.replace(a, b, c) + expect(asUint8Array(result)).toEqual(avmResult) + }) + + test.each([ + ['', 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}`) + }) + }) + + describe('select', async () => { + test.each([ + ['one', 'two', 0], + ['one', 'two', 1], + ['one', 'two', 2], + ['one', 'two', true], + ['one', 'two', false], + [new Uint8Array([0x00, 0x00, 0xff]), new Uint8Array([0xff]), 0n], + [new Uint8Array([0x00, 0x00, 0xff]), new Uint8Array([0xff]), 1n], + ])(`should select bytes according to the input`, async (a, b, c) => { + const avmResult = (await getAvmResultRaw( + { appClient }, + 'verify_select_bytes', + asUint8Array(a), + asUint8Array(b), + c === true ? 1 : c === false ? 0 : c, + ))! + const result = op.select(a, b, c) + expect(asUint8Array(result)).toEqual(avmResult) + }) + + test.each([ + [new Uint8Array([0x00, 0x00, 0xff]), new Uint8Array([0xff]), MAX_UINT64 + 1n], + [new Uint8Array([0x00, 0x00, 0xff]), new Uint8Array([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 over or underflow') + }) + + test.each([ + [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) => { + 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.valueOf()).toEqual(avmResult) + }) + + test.each([ + [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) => { + await expect(getAvmResult({ appClient }, 'verify_select_uint64', a, b, c)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.select(a, b, c)).toThrow('Uint64 over or underflow') + }) + }) + + describe('setBit', async () => { + test.each([ + [new Uint8Array([0x00]), 0, 1], + [getPaddedUint8Array(2, intToBytes(256)), 3, 1], + [getPaddedUint8Array(2, intToBytes(256)), 0, 1], + [getPaddedUint8Array(2, intToBytes(256)), 11, 1], + [getPaddedUint8Array(2, intToBytes(65535)), 31, 0], + [getPaddedUint8Array(2, intToBytes(65535)), 24, 0], + [intToBytes(MAX_UINT64), 63, 0], + [intToBytes(MAX_UINT64 - 1n), 63, 1], + [intToBytes(MAX_UINT512), 511, 0], + [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 getAvmResultRaw({ appClient }, 'verify_setbit_bytes', asUint8Array(a), b, c))! + const result = op.setBit(a, b, c) as bytes + expect(asUint8Array(result)).toEqual(avmResult) + }) + + test.each([ + [new Uint8Array([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/) + }) + + it('should throw error when input is invalid', async () => { + const a = new Uint8Array([0x00]) + const b = 0 + const c = 2 + await expect(getAvmResultRaw({ appClient }, 'verify_setbit_bytes', asUint8Array(a), b, c)).rejects.toThrow('setbit value > 1') + expect(() => op.setBit(a, b, c)).toThrow(`setBit value > 1`) + }) + + test.each([ + [0, 0, 1], + [0, 3, 1], + [0, 10, 1], + [256, 3, 1], + [256, 0, 1], + [256, 11, 1], + [65535, 15, 0], + [65535, 7, 0], + [65535, 63, 1], + [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) => { + const avmResult = await getAvmResult({ appClient }, 'verify_setbit_uint64', a, b, c) + const result = op.setBit(a, b, c) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + [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/) + }) + + it('should throw error when input is invalid', async () => { + const a = 0 + const b = 2 + const c = 2 + await expect(getAvmResult({ appClient }, 'verify_setbit_uint64', a, b, c)).rejects.toThrow('setbit value > 1') + expect(() => op.setBit(a, b, c)).toThrow(`setBit value > 1`) + }) + }) + + describe('setByte', async () => { + test.each([ + [new Uint8Array([0x00]), 0, 1], + [getPaddedUint8Array(2, intToBytes(256)), 3, 1], + [getPaddedUint8Array(2, intToBytes(256)), 0, 1], + [getPaddedUint8Array(2, intToBytes(256)), 1, 255], + [getPaddedUint8Array(2, intToBytes(65535)), 2, 0], + [getPaddedUint8Array(2, intToBytes(65535)), 2, 100], + [intToBytes(MAX_UINT64), 7, 0], + [intToBytes(MAX_UINT64 - 1n), 0, 42], + [intToBytes(MAX_UINT512), 63, 0], + [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 getAvmResultRaw({ appClient }, 'verify_setbyte', asUint8Array(a), b, c))! + const result = op.setByte(a, b, c) + expect(asUint8Array(result)).toEqual(avmResult) + }) + + test.each([ + [new Uint8Array([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( + 'setbyte index beyond array length', + ) + expect(() => op.setByte(a, b, c)).toThrow(`setByte index ${b} is beyond length`) + }) + + it('should throw error when input is invalid', async () => { + const a = new Uint8Array([0x00]) + const b = 0 + const c = 256 + await expect(getAvmResultRaw({ appClient }, 'verify_setbyte', asUint8Array(a), b, c)).rejects.toThrow('setbyte value > 255') + expect(() => op.setByte(a, b, c)).toThrow(`setByte value ${c} > 255`) + }) + }) + + describe('shl', async () => { + test.each([ + [0, 0], + [1, 0], + [0, 1], + [42, 0], + [100, 42], + [1, 63], + [MAX_UINT64 - 1n, 63], + [MAX_UINT64, 63], + ])(`should shift left the input`, async (a, b) => { + const avmResult = await getAvmResult({ appClient }, 'verify_shl', a, b) + const result = op.shl(a, b) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + [1, MAX_UINT64 + 1n], + [MAX_UINT64 + 1n, 1], + [0, MAX_UINT512], + [MAX_UINT512 * 2n, 0], + ])(`should throw error when input overflows`, async (a, b) => { + await expect(getAvmResult({ appClient }, 'verify_shl', a, b)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.shl(a, b)).toThrow('Uint64 over or underflow') + }) + + test.each([ + [1, MAX_UINT64], + [MAX_UINT64, 64], + ])(`should throw error when input is invalid`, async (a, b) => { + 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([ + [0, 0], + [1, 0], + [0, 1], + [111, 42], + [1, 63], + [MAX_UINT64 - 1n, 63], + [MAX_UINT64, 63], + ])('should shift right the input', async (a, b) => { + const avmResult = await getAvmResult({ appClient }, 'verify_shr', a, b) + const result = op.shr(a, b) + expect(result.valueOf()).toBe(avmResult) + }) + + test.each([ + [1, MAX_UINT64 + 1n], + [MAX_UINT64 + 1n, 1], + [0, MAX_UINT512], + [MAX_UINT512 * 2n, 1], + ])('should throw error when input overflows', async (a, b) => { + await expect(getAvmResult({ appClient }, 'verify_shr', a, b)).rejects.toThrow(avmIntArgOverflowError) + expect(() => op.shr(a, b)).toThrow('Uint64 over or underflow') + }) + + test.each([ + [1, MAX_UINT64], + [MAX_UINT64, 64], + ])('should throw error when input is invalid', async (a, b) => { + 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.valueOf()).toBe(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 over or underflow') + }) + }) + + describe('substring', async () => { + test.each([ + ['hello, world.', 5, 5], + ['hello, world.', 5, 6], + ['hello, world.', 5, 7], + ['hello, world.', 12, 13], + ['hello, world.', 11, 13], + ['hello, world.', 0, 1], + ['hello, world.', 0, 2], + ['hello, world.', 0, 13], + ['', 0, 0], + ])('should extract substring from the input', async (a, b, c) => { + const avmResult = (await getAvmResultRaw({ appClient }, 'verify_substring', asUint8Array(a), b, c))! + const result = op.substring(a, b, c) + expect(asUint8Array(result)).toEqual(avmResult) + }) + + test.each([ + ['', 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( + /(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([ + ['', 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 over or underflow') + }) + }) + + describe('jsonRef', async () => { + it('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/asset.spec.ts b/tests/references/asset.spec.ts new file mode 100644 index 0000000..9020bfd --- /dev/null +++ b/tests/references/asset.spec.ts @@ -0,0 +1,87 @@ +import { Account, Bytes, Uint64 } from '@algorandfoundation/algo-ts' +import { afterEach, describe, expect, it, test } from 'vitest' +import { TestExecutionContext } from '../../src' +import { AssetCls } from '../../src/impl/asset' +import { asBytes, asUint64 } from '../../src/util' +import { asUint8Array } from '../util' + +describe('Asset', () => { + const ctx = new TestExecutionContext() + + afterEach(() => { + ctx.reset() + }) + + it('can be initialised', () => { + let asset = new AssetCls() + expect(asset.id.valueOf()).toBe(0n) + + asset = new AssetCls(123) + expect(asset.id.valueOf()).toBe(123n) + + asset = new AssetCls(Uint64(456)) + expect(asset.id.valueOf()).toBe(456n) + + asset = new AssetCls(1n) + expect(asset.id.valueOf()).toBe(1n) + }) + + it('can have balance set and retrieved', () => { + const account = ctx.any.account() + const asset = ctx.any.asset() + ctx.ledger.updateAssetHolding(account, asset, 1000n) + + expect(asset.balance(account).valueOf()).toBe(1000n) + }) + + it('throws error for account not opted into when retrieving balance', () => { + const account = ctx.any.account() + const asset = ctx.any.asset() + + expect(() => asset.balance(account)).toThrowError('The asset is not opted into the account!') + }) + + test.each([true, false])('can have frozen status set and retrieved', (defaultFrozen) => { + const asset = ctx.any.asset({ defaultFrozen }) + const account = ctx.any.account({ optedAssetBalances: new Map([[asset.id, 0n]]) }) + + expect(asset.frozen(account)).toBe(defaultFrozen) + }) + + it('can have attributes set and retrieved', () => { + const assetData = { + total: asUint64(1000000), + decimals: asUint64(6), + defaultFrozen: false, + unitName: asBytes('TEST'), + name: asBytes('Test Asset'), + url: asBytes('https://test.com'), + metadataHash: Bytes(new Uint8Array(Array(32).fill(0x00))), + manager: Account(), + freeze: Account(), + clawback: Account(), + creator: Account(), + reserve: Account(), + } + + const asset = ctx.any.asset(assetData) + + expect(asset.total.valueOf()).toBe(assetData.total.valueOf()) + expect(asset.decimals.valueOf()).toBe(assetData.decimals.valueOf()) + expect(asset.defaultFrozen).toBe(assetData.defaultFrozen) + expect(asset.unitName.toString()).toEqual(assetData.unitName.toString()) + expect(asset.name.toString()).toEqual(assetData.name.toString()) + expect(asset.url.toString()).toEqual(assetData.url.toString()) + expect(asUint8Array(asset.metadataHash)).toEqual(asUint8Array(assetData.metadataHash)) + expect(asUint8Array(asset.manager.bytes)).toEqual(asUint8Array(assetData.manager.bytes)) + expect(asUint8Array(asset.freeze.bytes)).toEqual(asUint8Array(assetData.freeze.bytes)) + expect(asUint8Array(asset.clawback.bytes)).toEqual(asUint8Array(assetData.clawback.bytes)) + expect(asUint8Array(asset.creator.bytes)).toEqual(asUint8Array(assetData.creator.bytes)) + expect(asUint8Array(asset.reserve.bytes)).toEqual(asUint8Array(assetData.reserve.bytes)) + }) + + it('throws error when asset is not in context', () => { + const asset = new AssetCls(123) + expect(() => asset.total).toThrowError('Unknown asset, check correct testing context is active') + }) +}) diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts new file mode 100644 index 0000000..3f44326 --- /dev/null +++ b/tests/state-op-codes.spec.ts @@ -0,0 +1,299 @@ +import { Account, bytes, Bytes, internal, op, uint64, Uint64 } from '@algorandfoundation/algo-ts' +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { afterEach, describe, expect, it, test } from 'vitest' +import { TestExecutionContext } from '../src' +import { + generateTestAccount, + generateTestAsset, + getAlgorandAppClient, + getAlgorandAppClientWithApp, + getAvmResult, + getLocalNetDefaultAccount, + INITIAL_BALANCE_MICRO_ALGOS, +} from './avm-invoker' + +import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' +import { ZERO_ADDRESS } from '../src/constants' +import { AccountCls } from '../src/impl/account' +import { asBigInt, asNumber } from '../src/util' +import { AppExpectingEffects } from './artifacts/created-app-asset/contract.algo' +import { + StateAcctParamsGetContract, + StateAppParamsContract, + StateAssetHoldingContract, + StateAssetParamsContract, +} from './artifacts/state-ops/contract.algo' +import acctParamsAppSpecJson from './artifacts/state-ops/data/StateAcctParamsGetContract.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 { asUint8Array } from './util' + +describe('State op codes', async () => { + const ctx = new TestExecutionContext() + + afterEach(async () => { + ctx.reset() + }) + + describe('AcctParams', async () => { + const appClient = await getAlgorandAppClient(acctParamsAppSpecJson as AppSpec) + const dummyAccount = await generateTestAccount() + + test.each([ + ['verify_acct_balance', INITIAL_BALANCE_MICRO_ALGOS + 100_000], + ['verify_acct_min_balance', 100_000], + ['verify_acct_auth_addr', ZERO_ADDRESS], + ['verify_acct_total_num_uint', 0], + ['verify_acct_total_num_byte_slice', 0], + ['verify_acct_total_extra_app_pages', 0], + ['verify_acct_total_apps_created', 0], + ['verify_acct_total_apps_opted_in', 0], + ['verify_acct_total_assets_created', 0], + ['verify_acct_total_assets', 0], + ['verify_acct_total_boxes', 0], + ['verify_acct_total_box_bytes', 0], + ])('should return the correct field value of the account', async (methodName, expectedValue) => { + const mockAccount = ctx.any.account({ + address: dummyAccount.addr, + balance: Uint64(INITIAL_BALANCE_MICRO_ALGOS + 100000), + minBalance: Uint64(100000), + 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), + }) + + const avmResult = await getAvmResult({ appClient, sendParams: { fee: AlgoAmount.Algos(1000) } }, methodName, dummyAccount.addr) + + const mockContract = ctx.contract.create(StateAcctParamsGetContract) + const mockResult = mockContract[methodName as keyof StateAcctParamsGetContract](mockAccount) + if (mockResult instanceof AccountCls) { + expect(mockResult.bytes.valueOf()).toEqual(avmResult) + expect(mockResult.bytes.valueOf()).toEqual((expectedValue as bytes).valueOf()) + } else { + expect(mockResult.valueOf()).toEqual(avmResult) + expect(asNumber(mockResult as uint64)).toEqual(expectedValue) + } + }) + }) + + describe('AppParams', async () => { + const [appClient, app] = await getAlgorandAppClientWithApp(appParamsAppSpecJson as AppSpec) + const dummyAccount = await getLocalNetDefaultAccount() + test.each([ + ['verify_app_params_get_approval_program', undefined], + ['verify_app_params_get_clear_state_program', undefined], + ['verify_app_params_get_global_num_uint', 0], + ['verify_app_params_get_global_num_byte_slice', 0], + ['verify_app_params_get_local_num_uint', 0], + ['verify_app_params_get_local_num_byte_slice', 0], + ['verify_app_params_get_extra_program_pages', 0], + ['verify_app_params_get_creator', 'app.creator'], + ['verify_app_params_get_address', 'app.address'], + ])('should return the correct field value of the application', async (methodName, expectedValue) => { + 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(dummyAccount.addr)), + }) + const avmResult = await getAvmResult({ appClient, sendParams: { fee: AlgoAmount.Algos(1000) } }, methodName, app.appId) + + const mockContract = ctx.contract.create(StateAppParamsContract) + const mockResult = mockContract[methodName as keyof StateAppParamsContract](application) + + if (mockResult instanceof internal.primitives.BytesCls) { + expect([...asUint8Array(mockResult)]).toEqual(avmResult) + } else if (mockResult instanceof AccountCls) { + expect(mockResult.bytes.valueOf()).toEqual(avmResult) + const expected = + expectedValue === 'app.creator' ? application.creator : expectedValue === 'app.address' ? application.address : undefined + if (expected) { + expect(mockResult.bytes.valueOf()).toEqual(expected.bytes.valueOf()) + } + } else { + expect(mockResult.valueOf()).toEqual(avmResult) + expect(asNumber(mockResult as uint64)).toEqual(expectedValue) + } + }) + }) + + describe('AssetHolding', async () => { + const appClient = await getAlgorandAppClient(assetHoldingAppSpecJson as AppSpec) + const dummyAccount = await getLocalNetDefaultAccount() + test.each([ + ['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({ + creator: dummyAccount, + total: 100, + decimals: 0, + frozenByDefault: false, + }) + const avmResult = await getAvmResult({ appClient }, methodName, dummyAccount.addr, 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) + } + }) + }) + + describe('AssetParams', async () => { + const appClient = await getAlgorandAppClient(assetParamsAppSpecJson as AppSpec) + const dummyAccount = await getLocalNetDefaultAccount() + + test.each([ + ['verify_asset_params_get_total', 100n], + ['verify_asset_params_get_decimals', 0n], + ['verify_asset_params_get_default_frozen', false], + ['verify_asset_params_get_unit_name', Bytes('UNIT')], + ['verify_asset_params_get_name', Bytes('TEST')], + ['verify_asset_params_get_url', Bytes('https://algorand.co')], + ['verify_asset_params_get_metadata_hash', Bytes(`test${' '.repeat(28)}`)], + ['verify_asset_params_get_manager', ZERO_ADDRESS], + ['verify_asset_params_get_reserve', ZERO_ADDRESS], + ['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 = dummyAccount.addr + 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: Account(Bytes(creator)), + }) + + const dummyAsset = await generateTestAsset({ + creator: dummyAccount, + total: 100, + decimals: 0, + frozenByDefault: false, + name: 'TEST', + unit: 'UNIT', + url: 'https://algorand.co', + metadataHash: metadataHash.toString(), + }) + + const avmResult = await getAvmResult({ appClient }, methodName, asBigInt(dummyAsset)) + + const mockContract = ctx.contract.create(StateAssetParamsContract) + const mockResult = mockContract[methodName as keyof StateAssetParamsContract](mockAsset) + + if (mockResult instanceof internal.primitives.BytesCls) { + expect([...asUint8Array(mockResult)]).toEqual(avmResult) + expect(asUint8Array(mockResult)).toEqual(asUint8Array(expectedValue as bytes)) + } else if (mockResult instanceof AccountCls) { + expect(mockResult.bytes.valueOf()).toEqual(avmResult) + + const expectedString = expectedValue === 'creator' ? creator : (expectedValue as bytes).valueOf() + expect(mockResult.bytes.valueOf()).toEqual(expectedString) + } else { + expect(mockResult.valueOf()).toEqual(avmResult) + expect(mockResult.valueOf()).toEqual(expectedValue) + } + }) + }) + + describe('Global', async () => { + it('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 }) + let firstGroupId = Bytes() + let firstTimestamp = Uint64(0) + let secondGroupId = Bytes() + let secondTimestamp = Uint64(0) + ctx.txn.createScope([txn1]).execute(() => { + firstGroupId = op.Global.groupId + firstTimestamp = op.Global.latestTimestamp + expect(firstGroupId.length.valueOf()).toEqual(32n) + expect(firstTimestamp.valueOf()).not.toEqual(0n) + expect(op.Global.groupSize.valueOf()).toEqual(1n) + expect(op.Global.round.valueOf()).toEqual(1n) + expect(op.Global.callerApplicationId.valueOf()).toEqual(0n) + expect(op.Global.creatorAddress).toEqual(creator) + expect(op.Global.currentApplicationId).toEqual(app) + expect(op.Global.currentApplicationAddress).toEqual(app.address) + }) + const txn2 = ctx.any.txn.payment() + const txn3 = ctx.any.txn.applicationCall() + const caller = ctx.any.application() + ctx.ledger.patchGlobalData({ callerApplicationId: caller.id }) + ctx.txn.createScope([txn2, txn3]).execute(() => { + secondGroupId = op.Global.groupId + secondTimestamp = op.Global.latestTimestamp + expect(secondGroupId.length.valueOf()).toEqual(32n) + expect(secondTimestamp.valueOf()).not.toEqual(0n) + expect(op.Global.groupSize.valueOf()).toEqual(2n) + expect(op.Global.round.valueOf()).toEqual(2n) + expect(op.Global.callerApplicationId.valueOf()).toEqual(caller.id.valueOf()) + expect(op.Global.callerApplicationAddress).toEqual(caller.address) + }) + expect(asUint8Array(firstGroupId)).not.toEqual(asUint8Array(secondGroupId)) + expect(firstTimestamp.valueOf()).not.toEqual(secondTimestamp.valueOf()) + }) + }) + + describe('gaid', async () => { + it('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 }) + const appCreateTxn = ctx.any.txn.applicationCall({ createdApp }) + + const contract = ctx.contract.create(AppExpectingEffects) + const [assetId, appId] = contract.create_group(assetCreateTxn, appCreateTxn) + + expect(assetId.valueOf()).toEqual(createdAsset.id.valueOf()) + expect(appId.valueOf()).toEqual(createdApp.id.valueOf()) + }) + + it('should be able to pass app call txn as app arg', async () => { + const appCallTxn = ctx.any.txn.applicationCall({ + appArgs: [Bytes('some_value()uint64')], + appLogs: [Bytes('this is a log statement')], + }) + const contract = ctx.contract.create(AppExpectingEffects) + contract.log_group(appCallTxn) + }) + + // TODO: uncomment when arc4 stubs are implemented + // it('should be able to pass app call txn as app arg', async () => { + // const appCallTxn = ctx.any.txn.applicationCall({ + // appArgs: [arc4.arc4Signature("some_value()uint64")], + // logs: [arc4Prefix.concat(arc4.Uint64(2).bytes)] + // }) + // const contract = ctx.contract.create(AppExpectingEffects) + // contract.log_group(appCallTxn) + // }) + }) +}) diff --git a/tests/util.ts b/tests/util.ts new file mode 100644 index 0000000..ab436f9 --- /dev/null +++ b/tests/util.ts @@ -0,0 +1,27 @@ +import { Bytes, bytes, internal } from '@algorandfoundation/algo-ts' +import { createHash } from 'crypto' + +export const padUint8Array = (arr: Uint8Array, padSize: number): Uint8Array => { + const paddedUint8Array = new Uint8Array(arr.length + padSize).fill(0) + arr.forEach((v, i) => (paddedUint8Array[padSize + i] = v)) + return paddedUint8Array +} + +export const asUint8Array = (value: internal.primitives.StubBytesCompat): Uint8Array => + internal.primitives.BytesCls.fromCompat(value).asUint8Array() + +export const base64Encode = (value: Uint8Array | string): bytes => Bytes(Buffer.from(value).toString('base64')) + +export const base64UrlEncode = (value: Uint8Array | string): bytes => Bytes(Buffer.from(value).toString('base64url')) + +export const getSha256Hash = (value: Uint8Array): Uint8Array => new Uint8Array(createHash('sha256').update(value).digest()) + +export const getPaddedUint8Array = (padSize: number, value: internal.primitives.StubBytesCompat): Uint8Array => { + const uint8ArrayValue = asUint8Array(value) + const result = new Uint8Array(padSize + uint8ArrayValue.length) + result.set([...Array(padSize).fill(0x00), ...uint8ArrayValue]) + return result +} + +export const intToBytes = (value: internal.primitives.StubBigUintCompat): internal.primitives.BytesCls => + internal.primitives.BigUintCls.fromCompat(value).toBytes() diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 0000000..a491539 --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/", + "noEmit": false, + "declaration": true + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts", "src/**/tests/**", "examples/**/*.ts",] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..a00766d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "@tsconfig/node20/tsconfig.json", + "compilerOptions": { + "noEmit": true, + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "esModuleInterop": true + }, + "include": ["src/**/*.ts", "scripts/**/*.ts", "examples/**/*.ts", "rollup.config.ts", "tests/**/*.ts", "vitest.config.mts", "eslint.config.mjs" ], + "exclude": ["examples/**/*.spec.ts"] +} diff --git a/vitest.config.mts b/vitest.config.mts new file mode 100644 index 0000000..46d7902 --- /dev/null +++ b/vitest.config.mts @@ -0,0 +1,26 @@ +import typescript from '@rollup/plugin-typescript' +import { defineConfig } from 'vitest/config' +import { puyaTsTransformer } from './src/test-transformer' + +export default defineConfig({ + resolve: { + conditions: ['dev'], + }, + esbuild: {}, + plugins: [ + typescript({ + target: 'ES2022', + tsconfig: false, + exclude: ['node_modules'], + compilerOptions: { + lib: ['es2023'], + }, + transformers: { + before: [puyaTsTransformer], + }, + }), + ], + test: { + globals: true, + }, +}) From 8947d2fe95a6998341d4db80e28a42cb3152896a Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 27 Sep 2024 11:25:57 +0800 Subject: [PATCH 02/85] update import statements of awst components as puya-ts no longer export internal module --- package-lock.json | 9 ++++++++- src/test-transformer/index.ts | 2 +- src/test-transformer/node-factory.ts | 2 +- src/test-transformer/visitors.ts | 10 +--------- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 09a4e69..b908138 100644 --- a/package-lock.json +++ b/package-lock.json @@ -75,11 +75,18 @@ "glob": "^11.0.0", "polytype": "^0.17.0", "zod": "^3.23.8" + }, + "bin": { + "puya-ts": "bin/run-cli.mjs", + "puyats": "bin/run-cli.mjs" + }, + "peerDependencies": { + "@algorandfoundation/algo-ts": "0.0.1-alpha.1" } }, "../puya-ts/packages/algo-ts/dist": { "name": "@algorandfoundation/algo-ts", - "version": "1.0.0", + "version": "0.0.1-alpha.1", "dev": true, "peerDependencies": { "tslib": "^2.6.2" diff --git a/src/test-transformer/index.ts b/src/test-transformer/index.ts index bb11ff2..47bc33b 100644 --- a/src/test-transformer/index.ts +++ b/src/test-transformer/index.ts @@ -1,5 +1,5 @@ import type ts from 'typescript' -import { registerPTypes, typeRegistry } from '@algorandfoundation/puya-ts/internal' +import { registerPTypes, typeRegistry } from '@algorandfoundation/puya-ts' import type { DeliberateAny } from '../typescript-helpers' import { SourceFileVisitor } from './visitors' diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 564bdc4..0cd0aee 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -1,6 +1,6 @@ import ts from 'typescript' -import { FunctionPType } from '@algorandfoundation/puya-ts/internal' +import { FunctionPType } from '@algorandfoundation/puya-ts' import type { DeliberateAny } from '../typescript-helpers' import { getPropertyNameAsString } from './helpers' diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index c31920b..2744702 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -1,13 +1,5 @@ import ts from 'typescript' -import { - ContractClassPType, - FunctionPType, - PType, - SourceLocation, - TypeResolver, - anyPType, - typeRegistry, -} from '@algorandfoundation/puya-ts/internal' +import { ContractClassPType, FunctionPType, PType, SourceLocation, TypeResolver, anyPType, typeRegistry } from '@algorandfoundation/puya-ts' import { nodeFactory } from './node-factory' import { supportedBinaryOpString, supportedPrefixUnaryOpString } from './supported-binary-op-string' From 50701eac1100d8580c9e4edab656cd4df8cca99f Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 27 Sep 2024 18:18:22 +0800 Subject: [PATCH 03/85] implement itxn and itxn create op codes --- src/impl/app-params.ts | 2 +- src/impl/index.ts | 1 + src/impl/inner-transactions.ts | 176 +++++++ src/impl/itxn.ts | 646 +++++++++++++++++++++++++ src/impl/transactions.ts | 29 +- src/subcontexts/transaction-context.ts | 42 ++ src/util.ts | 31 +- 7 files changed, 916 insertions(+), 11 deletions(-) create mode 100644 src/impl/inner-transactions.ts create mode 100644 src/impl/itxn.ts diff --git a/src/impl/app-params.ts b/src/impl/app-params.ts index e5e0361..af1f9b7 100644 --- a/src/impl/app-params.ts +++ b/src/impl/app-params.ts @@ -11,7 +11,7 @@ const resolveAppIndex = (appIdOrIndex: internal.primitives.StubUint64Compat): ui return txn.apps(input).id } -const getApp = (app: Application | internal.primitives.StubUint64Compat): Application | undefined => { +export const getApp = (app: Application | internal.primitives.StubUint64Compat): Application | undefined => { try { const appId = asMaybeUint64Cls(app) if (appId !== undefined) { diff --git a/src/impl/index.ts b/src/impl/index.ts index 531347d..4adf1c7 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -7,3 +7,4 @@ export { Global } from './global' export { GTxn } from './gtxn' export * from './pure' export { Txn, gaid } from './txn' +export { ITxn, ITxnCreate } from './itxn' diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts new file mode 100644 index 0000000..8f42152 --- /dev/null +++ b/src/impl/inner-transactions.ts @@ -0,0 +1,176 @@ +import { Account, Application, arc4, Asset, bytes, internal, itxn, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import { + ApplicationTransaction, + AssetConfigTransaction, + AssetFreezeTransaction, + AssetTransferTransaction, + KeyRegistrationTransaction, + PaymentTransaction, +} from './transactions' +import { asBytes, toBytes } from '../util' +import { getAsset } from './asset-params' +import { InnerTxn, InnerTxnFields } from './itxn' +import { getApp } from './app-params' +import { Mutable } from '../typescript-helpers' +import { lazyContext } from '../context-helpers/internal-context' + +const mapCommonFields = ( + fields: T, +): Omit & { sender?: Account; note?: bytes; rekeyTo?: Account } => { + const { sender, note, rekeyTo, ...rest } = fields + return { + sender: sender instanceof Account ? sender : typeof sender === 'string' ? Account(asBytes(sender)) : undefined, + note: note !== undefined ? asBytes(note) : undefined, + rekeyTo: rekeyTo instanceof Account ? rekeyTo : typeof rekeyTo === 'string' ? Account(asBytes(rekeyTo)) : undefined, + ...rest, + } +} +export class PaymentInnerTxn extends PaymentTransaction implements itxn.PaymentInnerTxn { + readonly isItxn?: true + + /* @internal */ + static create(fields: itxn.PaymentFields) { + return new PaymentInnerTxn(fields) + } + + /* @internal */ + constructor(fields: itxn.PaymentFields) { + super(mapCommonFields(fields)) + } +} + +export class KeyRegistrationInnerTxn extends KeyRegistrationTransaction implements itxn.KeyRegistrationInnerTxn { + readonly isItxn?: true + + /* @internal */ + static create(fields: itxn.KeyRegistrationFields) { + return new KeyRegistrationInnerTxn(fields) + } + + /* @internal */ + constructor(fields: itxn.KeyRegistrationFields) { + super(mapCommonFields(fields)) + } +} + +export class AssetConfigInnerTxn extends AssetConfigTransaction implements itxn.AssetConfigInnerTxn { + readonly isItxn?: true + + /* @internal */ + static create(fields: itxn.AssetConfigFields) { + return new AssetConfigInnerTxn(fields) + } + + /* @internal */ + constructor(fields: itxn.AssetConfigFields) { + const { assetName, unitName, url, ...rest } = mapCommonFields(fields) + const createdAsset = lazyContext.any.asset({ + name: typeof assetName === 'string' ? asBytes(assetName) : assetName, + unitName: typeof unitName === 'string' ? asBytes(unitName) : unitName, + url: typeof url === 'string' ? asBytes(url) : url, + ...rest, + }) + + super({ + assetName: typeof assetName === 'string' ? asBytes(assetName) : assetName, + unitName: typeof unitName === 'string' ? asBytes(unitName) : unitName, + url: typeof url === 'string' ? asBytes(url) : url, + ...rest, + createdAsset: createdAsset, + }) + } +} + +export class AssetTransferInnerTxn extends AssetTransferTransaction implements itxn.AssetTransferInnerTxn { + readonly isItxn?: true + + /* @internal */ + static create(fields: Partial) { + if (fields.xferAsset === undefined) { + throw new Error('xferAsset is required') + } + return new AssetTransferInnerTxn(fields as itxn.AssetTransferFields) + } + + /* @internal */ + constructor(fields: itxn.AssetTransferFields) { + super(mapCommonFields(fields)) + } +} + +export class AssetFreezeInnerTxn extends AssetFreezeTransaction implements itxn.AssetFreezeInnerTxn { + readonly isItxn?: true + + /* @internal */ + static create(fields: Partial) { + if (fields.freezeAsset === undefined) { + throw new Error('freezeAsset is required') + } + return new AssetFreezeInnerTxn(fields as itxn.AssetFreezeFields) + } + + /* @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) + super({ + freezeAsset: asset, + freezeAccount: account, + ...rest, + }) + } +} + +export class ApplicationInnerTxn extends ApplicationTransaction implements itxn.ApplicationInnerTxn { + readonly isItxn?: true + + /* @internal */ + static create( + fields: Omit & { onCompletion?: arc4.OnCompleteAction | uint64 | arc4.OnCompleteActionStr }, + ) { + return new ApplicationInnerTxn(fields as itxn.ApplicationCallFields) + } + + /* @internal */ + constructor(fields: Mutable) { + const { appId, approvalProgram, clearStateProgram, onCompletion, appArgs, accounts, assets, apps, ...rest } = mapCommonFields(fields) + super({ + appId: appId instanceof internal.primitives.Uint64Cls ? getApp(appId) : (appId as Application), + onCompletion: + typeof onCompletion === 'string' + ? (onCompletion as arc4.OnCompleteActionStr) + : onCompletion !== undefined + ? (arc4.OnCompleteAction[onCompletion] as arc4.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) => toBytes(x)), + accounts: accounts?.map((x) => x), + assets: assets?.map((x) => x), + apps: apps?.map((x) => x), + ...rest, + }) + } +} + +export const createInnerTxn = (fields: InnerTxnFields): InnerTxn => { + switch (fields.type) { + case TransactionType.Payment: + return new PaymentInnerTxn(fields) + case TransactionType.AssetConfig: + return new AssetConfigInnerTxn(fields) + case TransactionType.AssetTransfer: + return new AssetTransferInnerTxn(fields as itxn.AssetTransferFields) + case TransactionType.AssetFreeze: + return new AssetFreezeInnerTxn(fields as itxn.AssetFreezeFields) + case TransactionType.ApplicationCall: + return new ApplicationInnerTxn(fields) + case TransactionType.KeyRegistration: + return new KeyRegistrationInnerTxn(fields) + default: + internal.errors.internalError(`Invalid inner transaction type: ${fields.type}`) + } +} diff --git a/src/impl/itxn.ts b/src/impl/itxn.ts new file mode 100644 index 0000000..59dd040 --- /dev/null +++ b/src/impl/itxn.ts @@ -0,0 +1,646 @@ +import { Account, Application, arc4, Asset, bytes, internal, itxn, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' +import { asBytes, asBytesCls, asUint64, asUint64Cls } from '../util' +import { getApp } from './app-params' +import { getAsset } from './asset-params' +import { testInvariant } from '../errors' +import { + ApplicationInnerTxn, + AssetConfigInnerTxn, + AssetFreezeInnerTxn, + AssetTransferInnerTxn, + KeyRegistrationInnerTxn, + PaymentInnerTxn, +} from './inner-transactions' + +export type InnerTxn = + | itxn.PaymentInnerTxn + | itxn.KeyRegistrationInnerTxn + | itxn.AssetConfigInnerTxn + | itxn.AssetTransferInnerTxn + | itxn.AssetFreezeInnerTxn + | itxn.ApplicationInnerTxn + +export type InnerTxnFields = ( + | itxn.PaymentFields + | itxn.KeyRegistrationFields + | itxn.AssetConfigFields + | itxn.AssetTransferFields + | itxn.AssetFreezeFields + | itxn.ApplicationCallFields +) & { type?: TransactionType } + +const getLastItxn = (): T => { + const innerTxnGroups = lazyContext.activeGroup.itxnGroups + testInvariant(innerTxnGroups.length > 0 && innerTxnGroups[-1].length > 0, 'no previous inner transactions') + return innerTxnGroups[-1][-1] as T +} + +export const ITxn: internal.opTypes.ITxnType = { + /** + * 32 byte address + */ + get sender(): Account { + return getLastItxn().sender + }, + /** + * microalgos + */ + get fee(): uint64 { + return getLastItxn().fee + }, + /** + * round number + */ + get firstValid(): uint64 { + return getLastItxn().firstValid + }, + /** + * UNIX timestamp of block before txn.FirstValid. Fails if negative + */ + get firstValidTime(): uint64 { + return getLastItxn().firstValidTime + }, + /** + * round number + */ + get lastValid(): uint64 { + return getLastItxn().lastValid + }, + /** + * Any data up to 1024 bytes + */ + get note(): bytes { + return getLastItxn().note + }, + /** + * 32 byte lease value + */ + get lease(): bytes { + return getLastItxn().lease + }, + /** + * 32 byte address + */ + get receiver(): Account { + return getLastItxn().receiver + }, + /** + * microalgos + */ + get amount(): uint64 { + return getLastItxn().amount + }, + /** + * 32 byte address + */ + get closeRemainderTo(): Account { + return getLastItxn().closeRemainderTo + }, + /** + * 32 byte address + */ + get votePk(): bytes { + return getLastItxn().voteKey + }, + /** + * 32 byte address + */ + get selectionPk(): bytes { + return getLastItxn().selectionKey + }, + /** + * The first round that the participation key is valid. + */ + get voteFirst(): uint64 { + return getLastItxn().voteFirst + }, + /** + * The last round that the participation key is valid. + */ + get voteLast(): uint64 { + return getLastItxn().voteLast + }, + /** + * Dilution for the 2-level participation key + */ + get voteKeyDilution(): uint64 { + return getLastItxn().voteKeyDilution + }, + /** + * Transaction type as bytes + */ + get type(): bytes { + return asUint64Cls(getLastItxn().type).toBytes().asAlgoTs() + }, + /** + * Transaction type as integer + */ + get typeEnum(): uint64 { + return asUint64(getLastItxn().type) + }, + /** + * Asset ID + */ + get xferAsset(): Asset { + return getLastItxn().xferAsset + }, + /** + * value in Asset's units + */ + get assetAmount(): uint64 { + return getLastItxn().assetAmount + }, + /** + * 32 byte address. Source of assets if Sender is the Asset's Clawback address. + */ + get assetSender(): Account { + return getLastItxn().assetSender + }, + /** + * 32 byte address + */ + get assetReceiver(): Account { + return getLastItxn().assetReceiver + }, + /** + * 32 byte address + */ + get assetCloseTo(): Account { + return getLastItxn().assetCloseTo + }, + /** + * Position of this transaction within an atomic transaction group. A stand-alone transaction is implicitly element 0 in a group of 1 + */ + get groupIndex(): uint64 { + return getLastItxn().groupIndex + }, + /** + * The computed ID for this transaction. 32 bytes. + */ + get txId(): bytes { + return getLastItxn().txnId + }, + /** + * ApplicationID from ApplicationCall transaction + */ + get applicationId(): Application { + return getLastItxn().appId + }, + /** + * ApplicationCall transaction on completion action + */ + get onCompletion(): uint64 { + const onCompletionStr = getLastItxn().onCompletion + return asUint64(arc4.OnCompleteAction[onCompletionStr]) + }, + /** + * Arguments passed to the application in the ApplicationCall transaction + */ + applicationArgs(a: internal.primitives.StubUint64Compat): bytes { + return getLastItxn().appArgs(asUint64(a)) + }, + /** + * Number of ApplicationArgs + */ + get numAppArgs(): uint64 { + return getLastItxn().numAppArgs + }, + /** + * Accounts listed in the ApplicationCall transaction + */ + accounts(a: internal.primitives.StubUint64Compat): Account { + return getLastItxn().accounts(asUint64(a)) + }, + /** + * Number of Accounts + */ + get numAccounts(): uint64 { + return getLastItxn().numAccounts + }, + /** + * Approval program + */ + get approvalProgram(): bytes { + return getLastItxn().approvalProgram + }, + /** + * Clear state program + */ + get clearStateProgram(): bytes { + return getLastItxn().clearStateProgram + }, + /** + * 32 byte Sender's new AuthAddr + */ + get rekeyTo(): Account { + return getLastItxn().rekeyTo + }, + /** + * Asset ID in asset config transaction + */ + get configAsset(): Asset { + return getLastItxn().configAsset + }, + /** + * Total number of units of this asset created + */ + get configAssetTotal(): uint64 { + return getLastItxn().total + }, + /** + * Number of digits to display after the decimal place when displaying the asset + */ + get configAssetDecimals(): uint64 { + return getLastItxn().decimals + }, + /** + * Whether the asset's slots are frozen by default or not, 0 or 1 + */ + get configAssetDefaultFrozen(): boolean { + return getLastItxn().defaultFrozen + }, + /** + * Unit name of the asset + */ + get configAssetUnitName(): bytes { + return getLastItxn().unitName + }, + /** + * The asset name + */ + get configAssetName(): bytes { + return getLastItxn().assetName + }, + /** + * URL + */ + get configAssetUrl(): bytes { + return getLastItxn().url + }, + /** + * 32 byte commitment to unspecified asset metadata + */ + get configAssetMetadataHash(): bytes { + return getLastItxn().metadataHash + }, + /** + * 32 byte address + */ + get configAssetManager(): Account { + return getLastItxn().manager + }, + /** + * 32 byte address + */ + get configAssetReserve(): Account { + return getLastItxn().reserve + }, + /** + * 32 byte address + */ + get configAssetFreeze(): Account { + return getLastItxn().freeze + }, + /** + * 32 byte address + */ + get configAssetClawback(): Account { + return getLastItxn().clawback + }, + /** + * Asset ID being frozen or un-frozen + */ + get freezeAsset(): Asset { + return getLastItxn().freezeAsset + }, + /** + * 32 byte address of the account whose asset slot is being frozen or un-frozen + */ + get freezeAssetAccount(): Account { + return getLastItxn().freezeAccount + }, + /** + * The new frozen value, 0 or 1 + */ + get freezeAssetFrozen(): boolean { + return getLastItxn().frozen + }, + /** + * Foreign Assets listed in the ApplicationCall transaction + */ + assets(a: internal.primitives.StubUint64Compat): Asset { + return getLastItxn().assets(asUint64(a)) + }, + /** + * Number of Assets + */ + get numAssets(): uint64 { + return getLastItxn().numAssets + }, + /** + * Foreign Apps listed in the ApplicationCall transaction + */ + applications(a: internal.primitives.StubUint64Compat): Application { + return getLastItxn().apps(asUint64(a)) + }, + /** + * Number of Applications + */ + get numApplications(): uint64 { + return getLastItxn().numApps + }, + /** + * Number of global state integers in ApplicationCall + */ + get globalNumUint(): uint64 { + return getLastItxn().globalNumUint + }, + /** + * Number of global state byteslices in ApplicationCall + */ + get globalNumByteSlice(): uint64 { + return getLastItxn().globalNumBytes + }, + /** + * Number of local state integers in ApplicationCall + */ + get localNumUint(): uint64 { + return getLastItxn().localNumUint + }, + /** + * Number of local state byteslices in ApplicationCall + */ + get localNumByteSlice(): uint64 { + return getLastItxn().localNumBytes + }, + /** + * Number of additional pages for each of the application's approval and clear state programs. An ExtraProgramPages of 1 means 2048 more total bytes, or 1024 for each program. + */ + get extraProgramPages(): uint64 { + return getLastItxn().extraProgramPages + }, + /** + * Marks an account nonparticipating for rewards + */ + get nonparticipation(): boolean { + return getLastItxn().nonparticipation + }, + /** + * Log messages emitted by an application call (only with `itxn` in v5). Application mode only + */ + logs(a: internal.primitives.StubUint64Compat): bytes { + return getLastItxn().logs(asUint64(a)) + }, + /** + * Number of Logs (only with `itxn` in v5). Application mode only + */ + get numLogs(): uint64 { + return getLastItxn().numLogs + }, + /** + * Asset ID allocated by the creation of an ASA (only with `itxn` in v5). Application mode only + */ + get createdAssetId(): Asset { + return getLastItxn().createdAsset + }, + /** + * ApplicationID allocated by the creation of an application (only with `itxn` in v5). Application mode only + */ + get createdApplicationId(): Application { + return getLastItxn().createdApp + }, + /** + * The last message emitted. Empty bytes if none were emitted. Application mode only + */ + get lastLog(): bytes { + return getLastItxn().lastLog + }, + /** + * 64 byte state proof public key + */ + get stateProofPk(): bytes { + return getLastItxn().stateProofKey + }, + /** + * Approval Program as an array of pages + */ + approvalProgramPages(a: internal.primitives.StubUint64Compat): bytes { + return getLastItxn().approvalProgramPages(asUint64(a)) + }, + /** + * Number of Approval Program pages + */ + get numApprovalProgramPages(): uint64 { + return getLastItxn().numApprovalProgramPages + }, + /** + * ClearState Program as an array of pages + */ + clearStateProgramPages(a: internal.primitives.StubUint64Compat): bytes { + return getLastItxn().clearStateProgramPages(asUint64(a)) + }, + /** + * Number of ClearState Program pages + */ + get numClearStateProgramPages(): uint64 { + return getLastItxn().numClearStateProgramPages + }, +} + +const setConstructingItxnField = (fields: Partial): void => { + Object.assign(lazyContext.activeGroup.constructingItxn, fields) +} + +const getConstructingItxn = (): T => { + return lazyContext.activeGroup.constructingItxn as T +} + +export const ITxnCreate: internal.opTypes.ITxnCreateType = { + begin: function (): void { + lazyContext.activeGroup.beginInnerTransactionGroup() + }, + setSender: function (a: Account): void { + setConstructingItxnField({ sender: a }) + }, + setFee: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ fee: asUint64(a) }) + }, + setNote: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ note: asBytes(a) }) + }, + setReceiver: function (a: Account): void { + setConstructingItxnField({ receiver: a }) + }, + setAmount: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ amount: asUint64(a) }) + }, + setCloseRemainderTo: function (a: Account): void { + setConstructingItxnField({ closeRemainderTo: a }) + }, + setVotePk: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ voteKey: asBytes(a) }) + }, + setSelectionPk: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ selectionKey: asBytes(a) }) + }, + setVoteFirst: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ voteFirst: asUint64(a) }) + }, + setVoteLast: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ voteLast: asUint64(a) }) + }, + setVoteKeyDilution: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ voteKeyDilution: asUint64(a) }) + }, + setType: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ type: asBytesCls(a).toUint64().asNumber() as TransactionType }) + }, + setTypeEnum: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ type: asUint64Cls(a).asNumber() as TransactionType }) + }, + setXferAsset: function (a: Asset | internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ xferAsset: getAsset(a) }) + }, + setAssetAmount: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ assetAmount: asUint64(a) }) + }, + setAssetSender: function (a: Account): void { + setConstructingItxnField({ assetSender: a }) + }, + setAssetReceiver: function (a: Account): void { + setConstructingItxnField({ assetReceiver: a }) + }, + setAssetCloseTo: function (a: Account): void { + setConstructingItxnField({ assetCloseTo: a }) + }, + setApplicationId: function (a: Application | internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ appId: getApp(a) }) + }, + setOnCompletion: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ onCompletion: asUint64(a) }) + }, + setApplicationArgs: function (a: internal.primitives.StubBytesCompat): void { + const appArgs = (getConstructingItxn().appArgs ?? []) as bytes[] + appArgs.push(asBytes(a)) + setConstructingItxnField({ appArgs }) + }, + setAccounts: function (a: Account): void { + const accounts = (getConstructingItxn().accounts ?? []) as Account[] + accounts.push(a) + setConstructingItxnField({ accounts }) + }, + setApprovalProgram: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ approvalProgram: asBytes(a) }) + }, + setClearStateProgram: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ clearStateProgram: asBytes(a) }) + }, + setRekeyTo: function (a: Account): void { + setConstructingItxnField({ rekeyTo: a }) + }, + setConfigAsset: function (a: Asset | internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ configAsset: getAsset(a) }) + }, + setConfigAssetTotal: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ total: asUint64(a) }) + }, + setConfigAssetDecimals: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ decimals: asUint64(a) }) + }, + setConfigAssetDefaultFrozen: function (a: boolean): void { + setConstructingItxnField({ defaultFrozen: a }) + }, + setConfigAssetUnitName: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ unitName: asBytes(a) }) + }, + setConfigAssetName: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ assetName: asBytes(a) }) + }, + setConfigAssetUrl: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ url: asBytes(a) }) + }, + setConfigAssetMetadataHash: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ metadataHash: asBytes(a) }) + }, + setConfigAssetManager: function (a: Account): void { + setConstructingItxnField({ manager: a }) + }, + setConfigAssetReserve: function (a: Account): void { + setConstructingItxnField({ reserve: a }) + }, + setConfigAssetFreeze: function (a: Account): void { + setConstructingItxnField({ freeze: a }) + }, + setConfigAssetClawback: function (a: Account): void { + setConstructingItxnField({ clawback: a }) + }, + setFreezeAsset: function (a: Asset | internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ freezeAsset: getAsset(a) }) + }, + setFreezeAssetAccount: function (a: Account): void { + setConstructingItxnField({ freezeAccount: a }) + }, + setFreezeAssetFrozen: function (a: boolean): void { + setConstructingItxnField({ frozen: a }) + }, + setAssets: function (a: internal.primitives.StubUint64Compat): void { + const asset = getAsset(a) + if (asset) { + const assets = (getConstructingItxn().assets ?? []) as Asset[] + assets.push(asset) + setConstructingItxnField({ assets }) + } + }, + setApplications: function (a: internal.primitives.StubUint64Compat): void { + const app = getApp(a) + if (app) { + const apps = (getConstructingItxn().apps ?? []) as Application[] + apps.push(app) + setConstructingItxnField({ apps }) + } + }, + setGlobalNumUint: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ globalNumUint: asUint64(a) }) + }, + setGlobalNumByteSlice: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ globalNumBytes: asUint64(a) }) + }, + setLocalNumUint: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ localNumUint: asUint64(a) }) + }, + setLocalNumByteSlice: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ localNumBytes: asUint64(a) }) + }, + setExtraProgramPages: function (a: internal.primitives.StubUint64Compat): void { + setConstructingItxnField({ extraProgramPages: asUint64(a) }) + }, + setNonparticipation: function (a: boolean): void { + setConstructingItxnField({ nonparticipation: a }) + }, + setStateProofPk: function (a: internal.primitives.StubBytesCompat): void { + setConstructingItxnField({ stateProofKey: asBytes(a) }) + }, + setApprovalProgramPages: function (a: internal.primitives.StubBytesCompat): void { + let pages = (getConstructingItxn().approvalProgram ?? []) as bytes[] + if (!Array.isArray(pages)) { + pages = [pages] + } + pages.push(asBytes(a)) + setConstructingItxnField({ approvalProgram: pages }) + }, + setClearStateProgramPages: function (a: internal.primitives.StubBytesCompat): void { + let pages = (getConstructingItxn().clearStateProgram ?? []) as bytes[] + if (!Array.isArray(pages)) { + pages = [pages] + } + pages.push(asBytes(a)) + setConstructingItxnField({ clearStateProgram: pages }) + }, + next: function (): void { + lazyContext.activeGroup.appendInnterTransactionGroup() + }, + submit: function (): void { + lazyContext.activeGroup.submitInnerTransactionGroup() + }, +} diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index efacbf2..f0c2807 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -1,5 +1,16 @@ -import { Account, Application, Asset, bytes, Bytes, gtxn, internal, TransactionType, uint64, Uint64 } from '@algorandfoundation/algo-ts' -import { OnCompleteActionStr } from '@algorandfoundation/algo-ts/arc4' +import { + Account, + Application, + arc4, + Asset, + bytes, + Bytes, + gtxn, + internal, + TransactionType, + uint64, + Uint64, +} from '@algorandfoundation/algo-ts' import { MAX_ITEMS_IN_LOG } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { Mutable, ObjectKeys } from '../typescript-helpers' @@ -56,7 +67,7 @@ export class PaymentTransaction extends TransactionBase implements gtxn.PaymentT return new PaymentTransaction(fields) } - private constructor(fields: TxnFields) { + protected constructor(fields: TxnFields) { super(fields) this.receiver = fields.receiver ?? Account() this.amount = fields.amount ?? Uint64(0) @@ -75,7 +86,7 @@ export class KeyRegistrationTransaction extends TransactionBase implements gtxn. return new KeyRegistrationTransaction(fields) } - private constructor(fields: TxnFields) { + protected constructor(fields: TxnFields) { super(fields) this.voteKey = fields.voteKey ?? Bytes() this.selectionKey = fields.selectionKey ?? Bytes() @@ -102,7 +113,7 @@ export class AssetConfigTransaction extends TransactionBase implements gtxn.Asse return new AssetConfigTransaction(fields) } - private constructor(fields: TxnFields) { + protected constructor(fields: TxnFields) { super(fields) this.configAsset = fields.configAsset ?? Asset() this.total = fields.total ?? Uint64(0) @@ -141,7 +152,7 @@ export class AssetTransferTransaction extends TransactionBase implements gtxn.As return new AssetTransferTransaction(fields) } - private constructor(fields: TxnFields) { + protected constructor(fields: TxnFields) { super(fields) this.xferAsset = fields.xferAsset ?? Asset() this.assetAmount = fields.assetAmount ?? Uint64(0) @@ -165,7 +176,7 @@ export class AssetFreezeTransaction extends TransactionBase implements gtxn.Asse return new AssetFreezeTransaction(fields) } - private constructor(fields: TxnFields) { + protected constructor(fields: TxnFields) { super(fields) this.freezeAsset = fields.freezeAsset ?? Asset() this.freezeAccount = fields.freezeAccount ?? Account() @@ -203,7 +214,7 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl #clearStateProgramPages: Array #appLogs: Array - private constructor(fields: ApplicationTransactionFields) { + protected constructor(fields: ApplicationTransactionFields) { super(fields) this.appId = fields.appId ?? Application() this.onCompletion = fields.onCompletion ?? 'NoOp' @@ -223,7 +234,7 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl } readonly appId: Application - readonly onCompletion: OnCompleteActionStr + readonly onCompletion: arc4.OnCompleteActionStr readonly globalNumUint: uint64 readonly globalNumBytes: uint64 readonly localNumUint: uint64 diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 01f40cc..a57c111 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -5,6 +5,8 @@ import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' import { testInvariant } from '../errors' import { AllTransactionFields, Transaction } from '../impl/transactions' import { asBigInt, asUint64 } from '../util' +import { InnerTxn, InnerTxnFields } from '../impl/itxn' +import { createInnerTxn } from '../impl/inner-transactions' function ScopeGenerator(dispose: () => void) { function* internal() { @@ -109,6 +111,8 @@ export class TransactionGroup { activeTransactionIndex: number latestTimestamp: number transactions: Transaction[] + itxnGroups: InnerTxn[][] = [] + constructingItxnGroup: InnerTxnFields[] = [] constructor(transactions: Transaction[], activeTransactionIndex?: number) { this.latestTimestamp = Date.now() @@ -134,9 +138,47 @@ export class TransactionGroup { return this.activeTransaction.appId.id } + get constructingItxn() { + if (!this.constructingItxnGroup.length) { + internal.errors.internalError('itxn field without itxn begin') + } + return this.constructingItxnGroup.at(-1)! + } + 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) } + + beginInnerTransactionGroup() { + if (this.constructingItxnGroup.length) { + internal.errors.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') + } + this.constructingItxnGroup.push({} as InnerTxnFields) + } + + appendInnterTransactionGroup() { + if (!this.constructingItxnGroup.length) { + internal.errors.internalError('itxn next without itxn begin') + } + this.constructingItxnGroup.push({} as InnerTxnFields) + } + + submitInnerTransactionGroup() { + if (!this.constructingItxnGroup.length) { + internal.errors.internalError('itxn submit without itxn begin') + } + if (this.constructingItxnGroup.length > algosdk.AtomicTransactionComposer.MAX_GROUP_SIZE) { + internal.errors.internalError('Cannot submit more than 16 inner transactions at once') + } + const itxns = this.constructingItxnGroup.map((t) => createInnerTxn(t)) + itxns.forEach((itxn, index) => Object.assign(itxn, { groupIndex: asUint64(index) })) + this.itxnGroups.push(itxns) + this.constructingItxnGroup = [] + } } diff --git a/src/util.ts b/src/util.ts index a4036dd..f059fcb 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,4 @@ -import { internal } from '@algorandfoundation/algo-ts' +import { internal, bytes } from '@algorandfoundation/algo-ts' import { randomBytes } from 'crypto' import { BITS_IN_BYTE, MAX_UINT512, MAX_UINT8, UINT512_SIZE } from './constants' import { DeliberateAny } from './typescript-helpers' @@ -42,6 +42,23 @@ export const asBigUint = (val: internal.primitives.StubBigUintCompat) => asBigUi export const asBytes = (val: internal.primitives.StubBytesCompat) => asBytesCls(val).asAlgoTs() +//TODO: handle arc4 types, bytes backed types +export const toBytes = (val: unknown): bytes => { + const uint64Val = asMaybeUint64Cls(val) + if (uint64Val !== undefined) { + return uint64Val.toBytes().asAlgoTs() + } + const bigUintVal = asMaybeBigUintCls(val) + if (bigUintVal !== undefined) { + return bigUintVal.toBytes().asAlgoTs() + } + const bytesVal = asMaybeBytesCls(val) + if (bytesVal !== undefined) { + return bytesVal.toBytes().asAlgoTs() + } + internal.errors.internalError(`Invalid type for bytes: ${nameOfType(val)}`) +} + export const asMaybeUint64Cls = (val: DeliberateAny) => { try { return internal.primitives.Uint64Cls.fromCompat(val) @@ -55,6 +72,18 @@ export const asMaybeUint64Cls = (val: DeliberateAny) => { return undefined } +export const asMaybeBigUintCls = (val: DeliberateAny) => { + try { + return internal.primitives.BigUintCls.fromCompat(val) + } catch (e) { + if (e instanceof internal.errors.InternalError) { + // swallow error and return undefined + } else { + throw e + } + } + return undefined +} export const asMaybeBytesCls = (val: DeliberateAny) => { try { return internal.primitives.BytesCls.fromCompat(val) From 5438a1b5665568a037a8f219ec9ee89499c11042 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 30 Sep 2024 13:36:03 +0800 Subject: [PATCH 04/85] implement get transaction by index functions --- package-lock.json | 4 +- src/impl/gtxn.ts | 178 ++++++++++++++++++++++------------ src/test-execution-context.ts | 21 ++++ 3 files changed, 138 insertions(+), 65 deletions(-) diff --git a/package-lock.json b/package-lock.json index b908138..81a6ee7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,11 +81,11 @@ "puyats": "bin/run-cli.mjs" }, "peerDependencies": { - "@algorandfoundation/algo-ts": "0.0.1-alpha.1" + "@algorandfoundation/algorand-typescript": "0.0.1-alpha.1" } }, "../puya-ts/packages/algo-ts/dist": { - "name": "@algorandfoundation/algo-ts", + "name": "@algorandfoundation/algorand-typescript", "version": "0.0.1-alpha.1", "dev": true, "peerDependencies": { diff --git a/src/impl/gtxn.ts b/src/impl/gtxn.ts index c53578a..382b3a2 100644 --- a/src/impl/gtxn.ts +++ b/src/impl/gtxn.ts @@ -1,15 +1,67 @@ -import { Account, Application, arc4, Asset, bytes, gtxn, internal, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, arc4, Asset, bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algo-ts' import { lazyContext } from '../context-helpers/internal-context' import { asNumber, asUint64, asUint64Cls } from '../util' +import { + ApplicationTransaction, + AssetConfigTransaction, + AssetFreezeTransaction, + AssetTransferTransaction, + KeyRegistrationTransaction, + PaymentTransaction, + Transaction, +} from './transactions' -const getTransaction = (t: internal.primitives.StubUint64Compat): T => { - const transactions = lazyContext.activeGroup.transactions - const index = asNumber(t) - if (index >= transactions.length) { - throw new internal.errors.InternalError('invalid group index') +export const getApplicationTransaction = (index?: internal.primitives.StubUint64Compat): ApplicationTransaction => { + return getTransactionImpl({ type: TransactionType.ApplicationCall, index }) as ApplicationTransaction +} +export const getAssetConfigTransaction = (index?: internal.primitives.StubUint64Compat): AssetConfigTransaction => { + return getTransactionImpl({ type: TransactionType.AssetConfig, index }) as AssetConfigTransaction +} +export const getAssetTransferTransaction = (index?: internal.primitives.StubUint64Compat): AssetTransferTransaction => { + return getTransactionImpl({ type: TransactionType.AssetTransfer, index }) as AssetTransferTransaction +} +export const getAssetFreezeTransaction = (index?: internal.primitives.StubUint64Compat): AssetFreezeTransaction => { + return getTransactionImpl({ type: TransactionType.AssetFreeze, index }) as AssetFreezeTransaction +} +export const getKeyRegistrationTransaction = (index?: internal.primitives.StubUint64Compat): KeyRegistrationTransaction => { + return getTransactionImpl({ type: TransactionType.KeyRegistration, index }) as KeyRegistrationTransaction +} +export const getPaymentTransaction = (index?: internal.primitives.StubUint64Compat): PaymentTransaction => { + return getTransactionImpl({ type: TransactionType.Payment, index }) as PaymentTransaction +} +export const getTransaction = (index?: internal.primitives.StubUint64Compat): Transaction => { + return getTransactionImpl({ index }) +} +const getTransactionImpl = ({ type, index }: { type?: TransactionType; index?: internal.primitives.StubUint64Compat }) => { + const i = index !== undefined ? asNumber(index) : undefined + if (i !== undefined && i >= lazyContext.activeGroup.transactions.length) { + throw new internal.errors.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}`) + } + switch (type) { + case TransactionType.ApplicationCall: + return transaction as ApplicationTransaction + case TransactionType.Payment: + return transaction as PaymentTransaction + case TransactionType.AssetConfig: + return transaction as AssetConfigTransaction + case TransactionType.AssetTransfer: + return transaction as AssetTransferTransaction + case TransactionType.AssetFreeze: + return transaction as AssetFreezeTransaction + case TransactionType.KeyRegistration: + return transaction as KeyRegistrationTransaction + default: + throw new internal.errors.InternalError(`Invalid transaction type: ${type}`) } - return transactions[index] as T } + export const GTxn: internal.opTypes.GTxnType = { sender(t: internal.primitives.StubUint64Compat): Account { return getTransaction(t).sender @@ -33,28 +85,28 @@ export const GTxn: internal.opTypes.GTxnType = { return getTransaction(t).lease }, receiver(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).receiver + return getPaymentTransaction(t).receiver }, amount(t: uint64): uint64 { - return getTransaction(t).amount + return getPaymentTransaction(t).amount }, closeRemainderTo(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).closeRemainderTo + return getPaymentTransaction(t).closeRemainderTo }, votePk(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).voteKey + return getKeyRegistrationTransaction(t).voteKey }, selectionPk(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).selectionKey + return getKeyRegistrationTransaction(t).selectionKey }, voteFirst(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).voteFirst + return getKeyRegistrationTransaction(t).voteFirst }, voteLast(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).voteLast + return getKeyRegistrationTransaction(t).voteLast }, voteKeyDilution(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).voteKeyDilution + return getKeyRegistrationTransaction(t).voteKeyDilution }, type(t: internal.primitives.StubUint64Compat): bytes { return asUint64Cls(getTransaction(t).type).toBytes().asAlgoTs() @@ -63,19 +115,19 @@ export const GTxn: internal.opTypes.GTxnType = { return asUint64(getTransaction(t).type) }, xferAsset(t: internal.primitives.StubUint64Compat): Asset { - return getTransaction(t).xferAsset + return getAssetTransferTransaction(t).xferAsset }, assetAmount(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).assetAmount + return getAssetTransferTransaction(t).assetAmount }, assetSender(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).assetSender + return getAssetTransferTransaction(t).assetSender }, assetReceiver(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).assetReceiver + return getAssetTransferTransaction(t).assetReceiver }, assetCloseTo(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).assetCloseTo + return getAssetTransferTransaction(t).assetCloseTo }, groupIndex(t: internal.primitives.StubUint64Compat): uint64 { return getTransaction(t).groupIndex @@ -84,136 +136,136 @@ export const GTxn: internal.opTypes.GTxnType = { return getTransaction(t).txnId }, applicationId(t: internal.primitives.StubUint64Compat): Application { - return getTransaction(t).appId + return getApplicationTransaction(t).appId }, onCompletion(t: internal.primitives.StubUint64Compat): uint64 { - const onCompletionStr = getTransaction(t).onCompletion + const onCompletionStr = getApplicationTransaction(t).onCompletion return asUint64(arc4.OnCompleteAction[onCompletionStr]) }, applicationArgs(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { - return getTransaction(a).appArgs(asUint64(b)) + return getApplicationTransaction(a).appArgs(asUint64(b)) }, numAppArgs(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).numAppArgs + return getApplicationTransaction(t).numAppArgs }, accounts(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Account { - return getTransaction(a).accounts(asUint64(b)) + return getApplicationTransaction(a).accounts(asUint64(b)) }, numAccounts(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).numAccounts + return getApplicationTransaction(t).numAccounts }, approvalProgram(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).approvalProgram + return getApplicationTransaction(t).approvalProgram }, clearStateProgram(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).clearStateProgram + return getApplicationTransaction(t).clearStateProgram }, rekeyTo(t: internal.primitives.StubUint64Compat): Account { return getTransaction(t).rekeyTo }, configAsset(t: internal.primitives.StubUint64Compat): Asset { - return getTransaction(t).configAsset + return getAssetConfigTransaction(t).configAsset }, configAssetTotal(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).total + return getAssetConfigTransaction(t).total }, configAssetDecimals(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).decimals + return getAssetConfigTransaction(t).decimals }, configAssetDefaultFrozen(t: internal.primitives.StubUint64Compat): boolean { - return getTransaction(t).defaultFrozen + return getAssetConfigTransaction(t).defaultFrozen }, configAssetUnitName(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).unitName + return getAssetConfigTransaction(t).unitName }, configAssetName(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).assetName + return getAssetConfigTransaction(t).assetName }, configAssetUrl(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).url + return getAssetConfigTransaction(t).url }, configAssetMetadataHash(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).metadataHash + return getAssetConfigTransaction(t).metadataHash }, configAssetManager(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).manager + return getAssetConfigTransaction(t).manager }, configAssetReserve(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).reserve + return getAssetConfigTransaction(t).reserve }, configAssetFreeze(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).freeze + return getAssetConfigTransaction(t).freeze }, configAssetClawback(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).clawback + return getAssetConfigTransaction(t).clawback }, freezeAsset(t: internal.primitives.StubUint64Compat): Asset { - return getTransaction(t).freezeAsset + return getAssetFreezeTransaction(t).freezeAsset }, freezeAssetAccount(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).freezeAccount + return getAssetFreezeTransaction(t).freezeAccount }, freezeAssetFrozen(t: internal.primitives.StubUint64Compat): boolean { - return getTransaction(t).frozen + return getAssetFreezeTransaction(t).frozen }, assets(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Asset { - return getTransaction(a).assets(asUint64(b)) + return getApplicationTransaction(a).assets(asUint64(b)) }, numAssets(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).numAssets + return getApplicationTransaction(t).numAssets }, applications(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Application { - return getTransaction(a).apps(asUint64(b)) + return getApplicationTransaction(a).apps(asUint64(b)) }, numApplications(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).numApps + return getApplicationTransaction(t).numApps }, globalNumUint(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).globalNumUint + return getApplicationTransaction(t).globalNumUint }, globalNumByteSlice(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).globalNumBytes + return getApplicationTransaction(t).globalNumBytes }, localNumUint(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).localNumUint + return getApplicationTransaction(t).localNumUint }, localNumByteSlice(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).localNumBytes + return getApplicationTransaction(t).localNumBytes }, extraProgramPages(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).extraProgramPages + return getApplicationTransaction(t).extraProgramPages }, nonparticipation(t: internal.primitives.StubUint64Compat): boolean { - return getTransaction(t).nonparticipation + return getKeyRegistrationTransaction(t).nonparticipation }, logs(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { - return getTransaction(a).logs(asUint64(b)) + return getApplicationTransaction(a).logs(asUint64(b)) }, numLogs(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).numLogs + return getApplicationTransaction(t).numLogs }, createdAssetId(t: internal.primitives.StubUint64Compat): Asset { - return getTransaction(t).createdAsset + return getAssetConfigTransaction(t).createdAsset }, createdApplicationId(t: internal.primitives.StubUint64Compat): Application { - return getTransaction(t).createdApp + return getApplicationTransaction(t).createdApp }, lastLog(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).lastLog + return getApplicationTransaction(t).lastLog }, stateProofPk(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).stateProofKey + return getKeyRegistrationTransaction(t).stateProofKey }, approvalProgramPages(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { - return getTransaction(a).approvalProgramPages(asUint64(b)) + return getApplicationTransaction(a).approvalProgramPages(asUint64(b)) }, numApprovalProgramPages(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).numApprovalProgramPages + return getApplicationTransaction(t).numApprovalProgramPages }, clearStateProgramPages(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { - return getTransaction(a).clearStateProgramPages(asUint64(b)) + return getApplicationTransaction(a).clearStateProgramPages(asUint64(b)) }, numClearStateProgramPages(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).numClearStateProgramPages + return getApplicationTransaction(t).numClearStateProgramPages }, } diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 950dcad..b53cb69 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -10,6 +10,15 @@ import { ContractContext } from './subcontexts/contract-context' import { LedgerContext } from './subcontexts/ledger-context' import { TransactionContext } from './subcontexts/transaction-context' import { ValueGenerator } from './value-generators' +import { + getApplicationTransaction, + getAssetConfigTransaction, + getAssetFreezeTransaction, + getAssetTransferTransaction, + getKeyRegistrationTransaction, + getPaymentTransaction, + getTransaction, +} from './impl/gtxn' export class TestExecutionContext implements internal.ExecutionContext { #applicationLogs: Map @@ -78,6 +87,18 @@ export class TestExecutionContext implements internal.ExecutionContext { } } + get gtxn() { + return { + Transaction: (index: uint64) => getTransaction(index), + PaymentTxn: (index: uint64) => getPaymentTransaction(index), + KeyRegistrationTxn: (index: uint64) => getKeyRegistrationTransaction(index), + AssetConfigTxn: (index: uint64) => getAssetConfigTransaction(index), + AssetTransferTxn: (index: uint64) => getAssetTransferTransaction(index), + AssetFreezeTxn: (index: uint64) => getAssetFreezeTransaction(index), + ApplicationTxn: (index: uint64) => getApplicationTransaction(index), + } + } + reset() { this.#applicationLogs.clear() this.#contractContext = new ContractContext() From 482e0eb5921846bfe5afe884880ee21cc863c43e Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 30 Sep 2024 18:45:21 +0800 Subject: [PATCH 05/85] implement gitxn op code and add tests for it and itxn --- src/impl/gtxn.ts | 200 ++++-------- src/impl/index.ts | 2 +- src/impl/inner-transactions.ts | 4 +- src/impl/itxn.ts | 358 ++++++++++++++++----- src/impl/transactions.ts | 19 +- src/impl/txn.ts | 151 ++++----- src/subcontexts/transaction-context.ts | 152 ++++++++- src/test-execution-context.ts | 23 +- src/util.ts | 15 +- tests/artifacts/state-ops/contract.algo.ts | 42 ++- tests/state-op-codes.spec.ts | 68 +++- 11 files changed, 710 insertions(+), 324 deletions(-) diff --git a/src/impl/gtxn.ts b/src/impl/gtxn.ts index 382b3a2..9d24afa 100644 --- a/src/impl/gtxn.ts +++ b/src/impl/gtxn.ts @@ -1,271 +1,211 @@ -import { Account, Application, arc4, Asset, bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, arc4, Asset, bytes, internal, uint64 } from '@algorandfoundation/algo-ts' import { lazyContext } from '../context-helpers/internal-context' -import { asNumber, asUint64, asUint64Cls } from '../util' -import { - ApplicationTransaction, - AssetConfigTransaction, - AssetFreezeTransaction, - AssetTransferTransaction, - KeyRegistrationTransaction, - PaymentTransaction, - Transaction, -} from './transactions' - -export const getApplicationTransaction = (index?: internal.primitives.StubUint64Compat): ApplicationTransaction => { - return getTransactionImpl({ type: TransactionType.ApplicationCall, index }) as ApplicationTransaction -} -export const getAssetConfigTransaction = (index?: internal.primitives.StubUint64Compat): AssetConfigTransaction => { - return getTransactionImpl({ type: TransactionType.AssetConfig, index }) as AssetConfigTransaction -} -export const getAssetTransferTransaction = (index?: internal.primitives.StubUint64Compat): AssetTransferTransaction => { - return getTransactionImpl({ type: TransactionType.AssetTransfer, index }) as AssetTransferTransaction -} -export const getAssetFreezeTransaction = (index?: internal.primitives.StubUint64Compat): AssetFreezeTransaction => { - return getTransactionImpl({ type: TransactionType.AssetFreeze, index }) as AssetFreezeTransaction -} -export const getKeyRegistrationTransaction = (index?: internal.primitives.StubUint64Compat): KeyRegistrationTransaction => { - return getTransactionImpl({ type: TransactionType.KeyRegistration, index }) as KeyRegistrationTransaction -} -export const getPaymentTransaction = (index?: internal.primitives.StubUint64Compat): PaymentTransaction => { - return getTransactionImpl({ type: TransactionType.Payment, index }) as PaymentTransaction -} -export const getTransaction = (index?: internal.primitives.StubUint64Compat): Transaction => { - return getTransactionImpl({ index }) -} -const getTransactionImpl = ({ type, index }: { type?: TransactionType; index?: internal.primitives.StubUint64Compat }) => { - const i = index !== undefined ? asNumber(index) : undefined - if (i !== undefined && i >= lazyContext.activeGroup.transactions.length) { - throw new internal.errors.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}`) - } - switch (type) { - case TransactionType.ApplicationCall: - return transaction as ApplicationTransaction - case TransactionType.Payment: - return transaction as PaymentTransaction - case TransactionType.AssetConfig: - return transaction as AssetConfigTransaction - case TransactionType.AssetTransfer: - return transaction as AssetTransferTransaction - case TransactionType.AssetFreeze: - return transaction as AssetFreezeTransaction - case TransactionType.KeyRegistration: - return transaction as KeyRegistrationTransaction - default: - throw new internal.errors.InternalError(`Invalid transaction type: ${type}`) - } -} +import { asUint64, asUint64Cls } from '../util' export const GTxn: internal.opTypes.GTxnType = { sender(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).sender + return lazyContext.activeGroup.getTransaction(t).sender }, fee(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).fee + return lazyContext.activeGroup.getTransaction(t).fee }, firstValid(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).firstValid + return lazyContext.activeGroup.getTransaction(t).firstValid }, firstValidTime(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).firstValidTime + return lazyContext.activeGroup.getTransaction(t).firstValidTime }, lastValid(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).lastValid + return lazyContext.activeGroup.getTransaction(t).lastValid }, note(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).note + return lazyContext.activeGroup.getTransaction(t).note }, lease(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).lease + return lazyContext.activeGroup.getTransaction(t).lease }, receiver(t: internal.primitives.StubUint64Compat): Account { - return getPaymentTransaction(t).receiver + return lazyContext.activeGroup.getPaymentTransaction(t).receiver }, amount(t: uint64): uint64 { - return getPaymentTransaction(t).amount + return lazyContext.activeGroup.getPaymentTransaction(t).amount }, closeRemainderTo(t: internal.primitives.StubUint64Compat): Account { - return getPaymentTransaction(t).closeRemainderTo + return lazyContext.activeGroup.getPaymentTransaction(t).closeRemainderTo }, votePk(t: internal.primitives.StubUint64Compat): bytes { - return getKeyRegistrationTransaction(t).voteKey + return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteKey }, selectionPk(t: internal.primitives.StubUint64Compat): bytes { - return getKeyRegistrationTransaction(t).selectionKey + return lazyContext.activeGroup.getKeyRegistrationTransaction(t).selectionKey }, voteFirst(t: internal.primitives.StubUint64Compat): uint64 { - return getKeyRegistrationTransaction(t).voteFirst + return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteFirst }, voteLast(t: internal.primitives.StubUint64Compat): uint64 { - return getKeyRegistrationTransaction(t).voteLast + return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteLast }, voteKeyDilution(t: internal.primitives.StubUint64Compat): uint64 { - return getKeyRegistrationTransaction(t).voteKeyDilution + return lazyContext.activeGroup.getKeyRegistrationTransaction(t).voteKeyDilution }, type(t: internal.primitives.StubUint64Compat): bytes { - return asUint64Cls(getTransaction(t).type).toBytes().asAlgoTs() + return asUint64Cls(lazyContext.activeGroup.getTransaction(t).type).toBytes().asAlgoTs() }, typeEnum(t: uint64): uint64 { - return asUint64(getTransaction(t).type) + return asUint64(lazyContext.activeGroup.getTransaction(t).type) }, xferAsset(t: internal.primitives.StubUint64Compat): Asset { - return getAssetTransferTransaction(t).xferAsset + return lazyContext.activeGroup.getAssetTransferTransaction(t).xferAsset }, assetAmount(t: internal.primitives.StubUint64Compat): uint64 { - return getAssetTransferTransaction(t).assetAmount + return lazyContext.activeGroup.getAssetTransferTransaction(t).assetAmount }, assetSender(t: internal.primitives.StubUint64Compat): Account { - return getAssetTransferTransaction(t).assetSender + return lazyContext.activeGroup.getAssetTransferTransaction(t).assetSender }, assetReceiver(t: internal.primitives.StubUint64Compat): Account { - return getAssetTransferTransaction(t).assetReceiver + return lazyContext.activeGroup.getAssetTransferTransaction(t).assetReceiver }, assetCloseTo(t: internal.primitives.StubUint64Compat): Account { - return getAssetTransferTransaction(t).assetCloseTo + return lazyContext.activeGroup.getAssetTransferTransaction(t).assetCloseTo }, groupIndex(t: internal.primitives.StubUint64Compat): uint64 { - return getTransaction(t).groupIndex + return lazyContext.activeGroup.getTransaction(t).groupIndex }, txId(t: internal.primitives.StubUint64Compat): bytes { - return getTransaction(t).txnId + return lazyContext.activeGroup.getTransaction(t).txnId }, applicationId(t: internal.primitives.StubUint64Compat): Application { - return getApplicationTransaction(t).appId + return lazyContext.activeGroup.getApplicationTransaction(t).appId }, onCompletion(t: internal.primitives.StubUint64Compat): uint64 { - const onCompletionStr = getApplicationTransaction(t).onCompletion + const onCompletionStr = lazyContext.activeGroup.getApplicationTransaction(t).onCompletion return asUint64(arc4.OnCompleteAction[onCompletionStr]) }, applicationArgs(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { - return getApplicationTransaction(a).appArgs(asUint64(b)) + return lazyContext.activeGroup.getApplicationTransaction(a).appArgs(asUint64(b)) }, numAppArgs(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).numAppArgs + return lazyContext.activeGroup.getApplicationTransaction(t).numAppArgs }, accounts(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Account { - return getApplicationTransaction(a).accounts(asUint64(b)) + return lazyContext.activeGroup.getApplicationTransaction(a).accounts(asUint64(b)) }, numAccounts(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).numAccounts + return lazyContext.activeGroup.getApplicationTransaction(t).numAccounts }, approvalProgram(t: internal.primitives.StubUint64Compat): bytes { - return getApplicationTransaction(t).approvalProgram + return lazyContext.activeGroup.getApplicationTransaction(t).approvalProgram }, clearStateProgram(t: internal.primitives.StubUint64Compat): bytes { - return getApplicationTransaction(t).clearStateProgram + return lazyContext.activeGroup.getApplicationTransaction(t).clearStateProgram }, rekeyTo(t: internal.primitives.StubUint64Compat): Account { - return getTransaction(t).rekeyTo + return lazyContext.activeGroup.getTransaction(t).rekeyTo }, configAsset(t: internal.primitives.StubUint64Compat): Asset { - return getAssetConfigTransaction(t).configAsset + return lazyContext.activeGroup.getAssetConfigTransaction(t).configAsset }, configAssetTotal(t: internal.primitives.StubUint64Compat): uint64 { - return getAssetConfigTransaction(t).total + return lazyContext.activeGroup.getAssetConfigTransaction(t).total }, configAssetDecimals(t: internal.primitives.StubUint64Compat): uint64 { - return getAssetConfigTransaction(t).decimals + return lazyContext.activeGroup.getAssetConfigTransaction(t).decimals }, configAssetDefaultFrozen(t: internal.primitives.StubUint64Compat): boolean { - return getAssetConfigTransaction(t).defaultFrozen + return lazyContext.activeGroup.getAssetConfigTransaction(t).defaultFrozen }, configAssetUnitName(t: internal.primitives.StubUint64Compat): bytes { - return getAssetConfigTransaction(t).unitName + return lazyContext.activeGroup.getAssetConfigTransaction(t).unitName }, configAssetName(t: internal.primitives.StubUint64Compat): bytes { - return getAssetConfigTransaction(t).assetName + return lazyContext.activeGroup.getAssetConfigTransaction(t).assetName }, configAssetUrl(t: internal.primitives.StubUint64Compat): bytes { - return getAssetConfigTransaction(t).url + return lazyContext.activeGroup.getAssetConfigTransaction(t).url }, configAssetMetadataHash(t: internal.primitives.StubUint64Compat): bytes { - return getAssetConfigTransaction(t).metadataHash + return lazyContext.activeGroup.getAssetConfigTransaction(t).metadataHash }, configAssetManager(t: internal.primitives.StubUint64Compat): Account { - return getAssetConfigTransaction(t).manager + return lazyContext.activeGroup.getAssetConfigTransaction(t).manager }, configAssetReserve(t: internal.primitives.StubUint64Compat): Account { - return getAssetConfigTransaction(t).reserve + return lazyContext.activeGroup.getAssetConfigTransaction(t).reserve }, configAssetFreeze(t: internal.primitives.StubUint64Compat): Account { - return getAssetConfigTransaction(t).freeze + return lazyContext.activeGroup.getAssetConfigTransaction(t).freeze }, configAssetClawback(t: internal.primitives.StubUint64Compat): Account { - return getAssetConfigTransaction(t).clawback + return lazyContext.activeGroup.getAssetConfigTransaction(t).clawback }, freezeAsset(t: internal.primitives.StubUint64Compat): Asset { - return getAssetFreezeTransaction(t).freezeAsset + return lazyContext.activeGroup.getAssetFreezeTransaction(t).freezeAsset }, freezeAssetAccount(t: internal.primitives.StubUint64Compat): Account { - return getAssetFreezeTransaction(t).freezeAccount + return lazyContext.activeGroup.getAssetFreezeTransaction(t).freezeAccount }, freezeAssetFrozen(t: internal.primitives.StubUint64Compat): boolean { - return getAssetFreezeTransaction(t).frozen + return lazyContext.activeGroup.getAssetFreezeTransaction(t).frozen }, assets(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Asset { - return getApplicationTransaction(a).assets(asUint64(b)) + return lazyContext.activeGroup.getApplicationTransaction(a).assets(asUint64(b)) }, numAssets(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).numAssets + return lazyContext.activeGroup.getApplicationTransaction(t).numAssets }, applications(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): Application { - return getApplicationTransaction(a).apps(asUint64(b)) + return lazyContext.activeGroup.getApplicationTransaction(a).apps(asUint64(b)) }, numApplications(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).numApps + return lazyContext.activeGroup.getApplicationTransaction(t).numApps }, globalNumUint(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).globalNumUint + return lazyContext.activeGroup.getApplicationTransaction(t).globalNumUint }, globalNumByteSlice(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).globalNumBytes + return lazyContext.activeGroup.getApplicationTransaction(t).globalNumBytes }, localNumUint(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).localNumUint + return lazyContext.activeGroup.getApplicationTransaction(t).localNumUint }, localNumByteSlice(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).localNumBytes + return lazyContext.activeGroup.getApplicationTransaction(t).localNumBytes }, extraProgramPages(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).extraProgramPages + return lazyContext.activeGroup.getApplicationTransaction(t).extraProgramPages }, nonparticipation(t: internal.primitives.StubUint64Compat): boolean { - return getKeyRegistrationTransaction(t).nonparticipation + return lazyContext.activeGroup.getKeyRegistrationTransaction(t).nonparticipation }, logs(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { - return getApplicationTransaction(a).logs(asUint64(b)) + return lazyContext.activeGroup.getApplicationTransaction(a).logs(asUint64(b)) }, numLogs(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).numLogs + return lazyContext.activeGroup.getApplicationTransaction(t).numLogs }, createdAssetId(t: internal.primitives.StubUint64Compat): Asset { - return getAssetConfigTransaction(t).createdAsset + return lazyContext.activeGroup.getAssetConfigTransaction(t).createdAsset }, createdApplicationId(t: internal.primitives.StubUint64Compat): Application { - return getApplicationTransaction(t).createdApp + return lazyContext.activeGroup.getApplicationTransaction(t).createdApp }, lastLog(t: internal.primitives.StubUint64Compat): bytes { - return getApplicationTransaction(t).lastLog + return lazyContext.activeGroup.getApplicationTransaction(t).lastLog }, stateProofPk(t: internal.primitives.StubUint64Compat): bytes { - return getKeyRegistrationTransaction(t).stateProofKey + return lazyContext.activeGroup.getKeyRegistrationTransaction(t).stateProofKey }, approvalProgramPages(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { - return getApplicationTransaction(a).approvalProgramPages(asUint64(b)) + return lazyContext.activeGroup.getApplicationTransaction(a).approvalProgramPages(asUint64(b)) }, numApprovalProgramPages(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).numApprovalProgramPages + return lazyContext.activeGroup.getApplicationTransaction(t).numApprovalProgramPages }, clearStateProgramPages(a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): bytes { - return getApplicationTransaction(a).clearStateProgramPages(asUint64(b)) + return lazyContext.activeGroup.getApplicationTransaction(a).clearStateProgramPages(asUint64(b)) }, numClearStateProgramPages(t: internal.primitives.StubUint64Compat): uint64 { - return getApplicationTransaction(t).numClearStateProgramPages + return lazyContext.activeGroup.getApplicationTransaction(t).numClearStateProgramPages }, } diff --git a/src/impl/index.ts b/src/impl/index.ts index 4adf1c7..5c5c373 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -7,4 +7,4 @@ export { Global } from './global' export { GTxn } from './gtxn' export * from './pure' export { Txn, gaid } from './txn' -export { ITxn, ITxnCreate } from './itxn' +export { GITxn, ITxn, ITxnCreate } from './itxn' diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts index 8f42152..93933d1 100644 --- a/src/impl/inner-transactions.ts +++ b/src/impl/inner-transactions.ts @@ -18,8 +18,10 @@ const mapCommonFields = ( fields: T, ): Omit & { sender?: Account; note?: bytes; rekeyTo?: Account } => { const { sender, note, rekeyTo, ...rest } = fields + return { - sender: sender instanceof Account ? sender : typeof sender === 'string' ? Account(asBytes(sender)) : undefined, + sender: + sender instanceof Account ? sender : typeof sender === 'string' ? Account(asBytes(sender)) : lazyContext.activeApplication.address, note: note !== undefined ? asBytes(note) : undefined, rekeyTo: rekeyTo instanceof Account ? rekeyTo : typeof rekeyTo === 'string' ? Account(asBytes(rekeyTo)) : undefined, ...rest, diff --git a/src/impl/itxn.ts b/src/impl/itxn.ts index 59dd040..aa09daa 100644 --- a/src/impl/itxn.ts +++ b/src/impl/itxn.ts @@ -3,15 +3,6 @@ import { lazyContext } from '../context-helpers/internal-context' import { asBytes, asBytesCls, asUint64, asUint64Cls } from '../util' import { getApp } from './app-params' import { getAsset } from './asset-params' -import { testInvariant } from '../errors' -import { - ApplicationInnerTxn, - AssetConfigInnerTxn, - AssetFreezeInnerTxn, - AssetTransferInnerTxn, - KeyRegistrationInnerTxn, - PaymentInnerTxn, -} from './inner-transactions' export type InnerTxn = | itxn.PaymentInnerTxn @@ -30,421 +21,622 @@ export type InnerTxnFields = ( | itxn.ApplicationCallFields ) & { type?: TransactionType } -const getLastItxn = (): T => { - const innerTxnGroups = lazyContext.activeGroup.itxnGroups - testInvariant(innerTxnGroups.length > 0 && innerTxnGroups[-1].length > 0, 'no previous inner transactions') - return innerTxnGroups[-1][-1] as T +export const GITxn: internal.opTypes.GITxnType = { + sender: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).sender + }, + fee: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).fee + }, + firstValid: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).firstValid + }, + firstValidTime: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).firstValidTime + }, + lastValid: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).lastValid + }, + note: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).note + }, + lease: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).lease + }, + receiver: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn(t).receiver + }, + amount: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn(t).amount + }, + closeRemainderTo: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn(t).closeRemainderTo + }, + votePk: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteKey + }, + selectionPk: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).selectionKey + }, + voteFirst: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteFirst + }, + voteLast: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteLast + }, + voteKeyDilution: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).voteKeyDilution + }, + type: function (t: internal.primitives.StubUint64Compat): bytes { + return asUint64Cls(lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).type).toBytes().asAlgoTs() + }, + typeEnum: function (t: internal.primitives.StubUint64Compat): uint64 { + return asUint64(lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).type) + }, + xferAsset: function (t: internal.primitives.StubUint64Compat): Asset { + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).xferAsset + }, + assetAmount: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetAmount + }, + assetSender: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetSender + }, + assetReceiver: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetReceiver + }, + assetCloseTo: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn(t).assetCloseTo + }, + groupIndex: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).groupIndex + }, + txId: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).txnId + }, + applicationId: function (t: internal.primitives.StubUint64Compat): Application { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).appId + }, + onCompletion: function (t: internal.primitives.StubUint64Compat): uint64 { + const onCompletionStr = lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).onCompletion + return asUint64(arc4.OnCompleteAction[onCompletionStr]) + }, + applicationArgs: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).appArgs(asUint64(a)) + }, + numAppArgs: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numAppArgs + }, + accounts: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).accounts(asUint64(a)) + }, + numAccounts: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numAccounts + }, + approvalProgram: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).approvalProgram + }, + clearStateProgram: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).clearStateProgram + }, + rekeyTo: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getInnerTxn(t).rekeyTo + }, + configAsset: function (t: internal.primitives.StubUint64Compat): Asset { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).configAsset + }, + configAssetTotal: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).total + }, + configAssetDecimals: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).decimals + }, + configAssetDefaultFrozen: function (t: internal.primitives.StubUint64Compat): boolean { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).defaultFrozen + }, + configAssetUnitName: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).unitName + }, + configAssetName: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).assetName + }, + configAssetUrl: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).url + }, + configAssetMetadataHash: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).metadataHash + }, + configAssetManager: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).manager + }, + configAssetReserve: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).reserve + }, + configAssetFreeze: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).freeze + }, + configAssetClawback: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).clawback + }, + freezeAsset: function (t: internal.primitives.StubUint64Compat): Asset { + return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn(t).freezeAsset + }, + freezeAssetAccount: function (t: internal.primitives.StubUint64Compat): Account { + return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn(t).freezeAccount + }, + freezeAssetFrozen: function (t: internal.primitives.StubUint64Compat): boolean { + return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn(t).frozen + }, + assets: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): Asset { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).assets(asUint64(a)) + }, + numAssets: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numAssets + }, + applications: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): Application { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).apps(asUint64(a)) + }, + numApplications: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numApps + }, + globalNumUint: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).globalNumUint + }, + globalNumByteSlice: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).globalNumBytes + }, + localNumUint: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).localNumUint + }, + localNumByteSlice: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).localNumBytes + }, + extraProgramPages: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).extraProgramPages + }, + nonparticipation: function (t: internal.primitives.StubUint64Compat): boolean { + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).nonparticipation + }, + logs: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).logs(asUint64(a)) + }, + numLogs: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numLogs + }, + createdAssetId: function (t: internal.primitives.StubUint64Compat): Asset { + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn(t).createdAsset + }, + createdApplicationId: function (t: internal.primitives.StubUint64Compat): Application { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).createdApp + }, + lastLog: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).lastLog + }, + stateProofPk: function (t: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn(t).stateProofKey + }, + approvalProgramPages: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).approvalProgramPages(asUint64(a)) + }, + numApprovalProgramPages: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numApprovalProgramPages + }, + clearStateProgramPages: function (t: internal.primitives.StubUint64Compat, a: internal.primitives.StubUint64Compat): bytes { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).clearStateProgramPages(asUint64(a)) + }, + numClearStateProgramPages: function (t: internal.primitives.StubUint64Compat): uint64 { + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn(t).numClearStateProgramPages + }, } - export const ITxn: internal.opTypes.ITxnType = { /** * 32 byte address */ get sender(): Account { - return getLastItxn().sender + return lazyContext.activeGroup.getItxnGroup().getInnerTxn().sender }, /** * microalgos */ get fee(): uint64 { - return getLastItxn().fee + return lazyContext.activeGroup.getItxnGroup().getInnerTxn().fee }, /** * round number */ get firstValid(): uint64 { - return getLastItxn().firstValid + return lazyContext.activeGroup.getItxnGroup().getInnerTxn().firstValid }, /** * UNIX timestamp of block before txn.FirstValid. Fails if negative */ get firstValidTime(): uint64 { - return getLastItxn().firstValidTime + return lazyContext.activeGroup.getItxnGroup().getInnerTxn().firstValidTime }, /** * round number */ get lastValid(): uint64 { - return getLastItxn().lastValid + return lazyContext.activeGroup.getItxnGroup().getInnerTxn().lastValid }, /** * Any data up to 1024 bytes */ get note(): bytes { - return getLastItxn().note + return lazyContext.activeGroup.getItxnGroup().getInnerTxn().note }, /** * 32 byte lease value */ get lease(): bytes { - return getLastItxn().lease + return lazyContext.activeGroup.getItxnGroup().getInnerTxn().lease }, /** * 32 byte address */ get receiver(): Account { - return getLastItxn().receiver + return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn().receiver }, /** * microalgos */ get amount(): uint64 { - return getLastItxn().amount + return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn().amount }, /** * 32 byte address */ get closeRemainderTo(): Account { - return getLastItxn().closeRemainderTo + return lazyContext.activeGroup.getItxnGroup().getPaymentInnerTxn().closeRemainderTo }, /** * 32 byte address */ get votePk(): bytes { - return getLastItxn().voteKey + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn().voteKey }, /** * 32 byte address */ get selectionPk(): bytes { - return getLastItxn().selectionKey + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn().selectionKey }, /** * The first round that the participation key is valid. */ get voteFirst(): uint64 { - return getLastItxn().voteFirst + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn().voteFirst }, /** * The last round that the participation key is valid. */ get voteLast(): uint64 { - return getLastItxn().voteLast + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn().voteLast }, /** * Dilution for the 2-level participation key */ get voteKeyDilution(): uint64 { - return getLastItxn().voteKeyDilution + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn().voteKeyDilution }, /** * Transaction type as bytes */ get type(): bytes { - return asUint64Cls(getLastItxn().type).toBytes().asAlgoTs() + return asUint64Cls(lazyContext.activeGroup.getItxnGroup().getInnerTxn().type).toBytes().asAlgoTs() }, /** * Transaction type as integer */ get typeEnum(): uint64 { - return asUint64(getLastItxn().type) + return asUint64(lazyContext.activeGroup.getItxnGroup().getInnerTxn().type) }, /** * Asset ID */ get xferAsset(): Asset { - return getLastItxn().xferAsset + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn().xferAsset }, /** * value in Asset's units */ get assetAmount(): uint64 { - return getLastItxn().assetAmount + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn().assetAmount }, /** * 32 byte address. Source of assets if Sender is the Asset's Clawback address. */ get assetSender(): Account { - return getLastItxn().assetSender + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn().assetSender }, /** * 32 byte address */ get assetReceiver(): Account { - return getLastItxn().assetReceiver + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn().assetReceiver }, /** * 32 byte address */ get assetCloseTo(): Account { - return getLastItxn().assetCloseTo + return lazyContext.activeGroup.getItxnGroup().getAssetTransferInnerTxn().assetCloseTo }, /** * Position of this transaction within an atomic transaction group. A stand-alone transaction is implicitly element 0 in a group of 1 */ get groupIndex(): uint64 { - return getLastItxn().groupIndex + return lazyContext.activeGroup.getItxnGroup().getInnerTxn().groupIndex }, /** * The computed ID for this transaction. 32 bytes. */ get txId(): bytes { - return getLastItxn().txnId + return lazyContext.activeGroup.getItxnGroup().getInnerTxn().txnId }, /** * ApplicationID from ApplicationCall transaction */ get applicationId(): Application { - return getLastItxn().appId + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().appId }, /** * ApplicationCall transaction on completion action */ get onCompletion(): uint64 { - const onCompletionStr = getLastItxn().onCompletion + const onCompletionStr = lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().onCompletion return asUint64(arc4.OnCompleteAction[onCompletionStr]) }, /** * Arguments passed to the application in the ApplicationCall transaction */ applicationArgs(a: internal.primitives.StubUint64Compat): bytes { - return getLastItxn().appArgs(asUint64(a)) + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().appArgs(asUint64(a)) }, /** * Number of ApplicationArgs */ get numAppArgs(): uint64 { - return getLastItxn().numAppArgs + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().numAppArgs }, /** * Accounts listed in the ApplicationCall transaction */ accounts(a: internal.primitives.StubUint64Compat): Account { - return getLastItxn().accounts(asUint64(a)) + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().accounts(asUint64(a)) }, /** * Number of Accounts */ get numAccounts(): uint64 { - return getLastItxn().numAccounts + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().numAccounts }, /** * Approval program */ get approvalProgram(): bytes { - return getLastItxn().approvalProgram + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().approvalProgram }, /** * Clear state program */ get clearStateProgram(): bytes { - return getLastItxn().clearStateProgram + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().clearStateProgram }, /** * 32 byte Sender's new AuthAddr */ get rekeyTo(): Account { - return getLastItxn().rekeyTo + return lazyContext.activeGroup.getItxnGroup().getInnerTxn().rekeyTo }, /** * Asset ID in asset config transaction */ get configAsset(): Asset { - return getLastItxn().configAsset + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().configAsset }, /** * Total number of units of this asset created */ get configAssetTotal(): uint64 { - return getLastItxn().total + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().total }, /** * Number of digits to display after the decimal place when displaying the asset */ get configAssetDecimals(): uint64 { - return getLastItxn().decimals + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().decimals }, /** * Whether the asset's slots are frozen by default or not, 0 or 1 */ get configAssetDefaultFrozen(): boolean { - return getLastItxn().defaultFrozen + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().defaultFrozen }, /** * Unit name of the asset */ get configAssetUnitName(): bytes { - return getLastItxn().unitName + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().unitName }, /** * The asset name */ get configAssetName(): bytes { - return getLastItxn().assetName + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().assetName }, /** * URL */ get configAssetUrl(): bytes { - return getLastItxn().url + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().url }, /** * 32 byte commitment to unspecified asset metadata */ get configAssetMetadataHash(): bytes { - return getLastItxn().metadataHash + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().metadataHash }, /** * 32 byte address */ get configAssetManager(): Account { - return getLastItxn().manager + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().manager }, /** * 32 byte address */ get configAssetReserve(): Account { - return getLastItxn().reserve + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().reserve }, /** * 32 byte address */ get configAssetFreeze(): Account { - return getLastItxn().freeze + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().freeze }, /** * 32 byte address */ get configAssetClawback(): Account { - return getLastItxn().clawback + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().clawback }, /** * Asset ID being frozen or un-frozen */ get freezeAsset(): Asset { - return getLastItxn().freezeAsset + return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn().freezeAsset }, /** * 32 byte address of the account whose asset slot is being frozen or un-frozen */ get freezeAssetAccount(): Account { - return getLastItxn().freezeAccount + return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn().freezeAccount }, /** * The new frozen value, 0 or 1 */ get freezeAssetFrozen(): boolean { - return getLastItxn().frozen + return lazyContext.activeGroup.getItxnGroup().getAssetFreezeInnerTxn().frozen }, /** * Foreign Assets listed in the ApplicationCall transaction */ assets(a: internal.primitives.StubUint64Compat): Asset { - return getLastItxn().assets(asUint64(a)) + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().assets(asUint64(a)) }, /** * Number of Assets */ get numAssets(): uint64 { - return getLastItxn().numAssets + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().numAssets }, /** * Foreign Apps listed in the ApplicationCall transaction */ applications(a: internal.primitives.StubUint64Compat): Application { - return getLastItxn().apps(asUint64(a)) + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().apps(asUint64(a)) }, /** * Number of Applications */ get numApplications(): uint64 { - return getLastItxn().numApps + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().numApps }, /** * Number of global state integers in ApplicationCall */ get globalNumUint(): uint64 { - return getLastItxn().globalNumUint + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().globalNumUint }, /** * Number of global state byteslices in ApplicationCall */ get globalNumByteSlice(): uint64 { - return getLastItxn().globalNumBytes + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().globalNumBytes }, /** * Number of local state integers in ApplicationCall */ get localNumUint(): uint64 { - return getLastItxn().localNumUint + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().localNumUint }, /** * Number of local state byteslices in ApplicationCall */ get localNumByteSlice(): uint64 { - return getLastItxn().localNumBytes + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().localNumBytes }, /** * Number of additional pages for each of the application's approval and clear state programs. An ExtraProgramPages of 1 means 2048 more total bytes, or 1024 for each program. */ get extraProgramPages(): uint64 { - return getLastItxn().extraProgramPages + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().extraProgramPages }, /** * Marks an account nonparticipating for rewards */ get nonparticipation(): boolean { - return getLastItxn().nonparticipation + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn().nonparticipation }, /** * Log messages emitted by an application call (only with `itxn` in v5). Application mode only */ logs(a: internal.primitives.StubUint64Compat): bytes { - return getLastItxn().logs(asUint64(a)) + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().logs(asUint64(a)) }, /** * Number of Logs (only with `itxn` in v5). Application mode only */ get numLogs(): uint64 { - return getLastItxn().numLogs + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().numLogs }, /** * Asset ID allocated by the creation of an ASA (only with `itxn` in v5). Application mode only */ get createdAssetId(): Asset { - return getLastItxn().createdAsset + return lazyContext.activeGroup.getItxnGroup().getAssetConfigInnerTxn().createdAsset }, /** * ApplicationID allocated by the creation of an application (only with `itxn` in v5). Application mode only */ get createdApplicationId(): Application { - return getLastItxn().createdApp + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().createdApp }, /** * The last message emitted. Empty bytes if none were emitted. Application mode only */ get lastLog(): bytes { - return getLastItxn().lastLog + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().lastLog }, /** * 64 byte state proof public key */ get stateProofPk(): bytes { - return getLastItxn().stateProofKey + return lazyContext.activeGroup.getItxnGroup().getKeyRegistrationInnerTxn().stateProofKey }, /** * Approval Program as an array of pages */ approvalProgramPages(a: internal.primitives.StubUint64Compat): bytes { - return getLastItxn().approvalProgramPages(asUint64(a)) + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().approvalProgramPages(asUint64(a)) }, /** * Number of Approval Program pages */ get numApprovalProgramPages(): uint64 { - return getLastItxn().numApprovalProgramPages + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().numApprovalProgramPages }, /** * ClearState Program as an array of pages */ clearStateProgramPages(a: internal.primitives.StubUint64Compat): bytes { - return getLastItxn().clearStateProgramPages(asUint64(a)) + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().clearStateProgramPages(asUint64(a)) }, /** * Number of ClearState Program pages */ get numClearStateProgramPages(): uint64 { - return getLastItxn().numClearStateProgramPages + return lazyContext.activeGroup.getItxnGroup().getApplicationInnerTxn().numClearStateProgramPages }, } @@ -638,7 +830,7 @@ export const ITxnCreate: internal.opTypes.ITxnCreateType = { setConstructingItxnField({ clearStateProgram: pages }) }, next: function (): void { - lazyContext.activeGroup.appendInnterTransactionGroup() + lazyContext.activeGroup.appendInnerTransactionGroup() }, submit: function (): void { lazyContext.activeGroup.submitInnerTransactionGroup() diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index f0c2807..de4fe08 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -14,7 +14,7 @@ import { import { MAX_ITEMS_IN_LOG } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { Mutable, ObjectKeys } from '../typescript-helpers' -import { asBytes, asNumber, getRandomBytes } from '../util' +import { asBytes, asNumber, asUint64Cls, combineIntoMaxBytePages, getRandomBytes } from '../util' const baseDefaultFields = () => ({ sender: lazyContext.defaultSender, @@ -24,7 +24,6 @@ const baseDefaultFields = () => ({ lastValid: Uint64(0), note: Bytes(), lease: Bytes(), - typeBytes: Bytes(), groupIndex: Uint64(0), txnId: getRandomBytes(32).asAlgoTs(), rekeyTo: Account(), @@ -42,7 +41,6 @@ abstract class TransactionBase { this.lastValid = fields.lastValid ?? baseDefaults.lastValid this.note = fields.note ?? baseDefaults.note this.lease = fields.lease ?? baseDefaults.lease - this.typeBytes = fields.typeBytes ?? baseDefaults.typeBytes this.groupIndex = fields.groupIndex ?? baseDefaults.groupIndex this.txnId = fields.txnId ?? baseDefaults.txnId this.rekeyTo = fields.rekeyTo ?? baseDefaults.rekeyTo @@ -55,7 +53,6 @@ abstract class TransactionBase { readonly lastValid: uint64 readonly note: bytes readonly lease: bytes - readonly typeBytes: bytes readonly groupIndex: uint64 readonly txnId: bytes readonly rekeyTo: Account @@ -78,6 +75,7 @@ export class PaymentTransaction extends TransactionBase implements gtxn.PaymentT readonly amount: uint64 readonly closeRemainderTo: Account readonly type: TransactionType.Payment = TransactionType.Payment + readonly typeBytes: bytes = asUint64Cls(TransactionType.Payment).toBytes().asAlgoTs() } export class KeyRegistrationTransaction extends TransactionBase implements gtxn.KeyRegistrationTxn { @@ -105,6 +103,7 @@ export class KeyRegistrationTransaction extends TransactionBase implements gtxn. readonly nonparticipation: boolean readonly stateProofKey: bytes readonly type: TransactionType.KeyRegistration = TransactionType.KeyRegistration + readonly typeBytes: bytes = asUint64Cls(TransactionType.KeyRegistration).toBytes().asAlgoTs() } export class AssetConfigTransaction extends TransactionBase implements gtxn.AssetConfigTxn { @@ -144,6 +143,7 @@ export class AssetConfigTransaction extends TransactionBase implements gtxn.Asse readonly clawback: Account readonly createdAsset: Asset readonly type: TransactionType.AssetConfig = TransactionType.AssetConfig + readonly typeBytes: bytes = asUint64Cls(TransactionType.AssetConfig).toBytes().asAlgoTs() } export class AssetTransferTransaction extends TransactionBase implements gtxn.AssetTransferTxn { @@ -168,6 +168,7 @@ export class AssetTransferTransaction extends TransactionBase implements gtxn.As readonly assetCloseTo: Account readonly type: TransactionType.AssetTransfer = TransactionType.AssetTransfer + readonly typeBytes: bytes = asUint64Cls(TransactionType.AssetTransfer).toBytes().asAlgoTs() } export class AssetFreezeTransaction extends TransactionBase implements gtxn.AssetFreezeTxn { @@ -188,6 +189,7 @@ export class AssetFreezeTransaction extends TransactionBase implements gtxn.Asse readonly frozen: boolean readonly type: TransactionType.AssetFreeze = TransactionType.AssetFreeze + readonly typeBytes: bytes = asUint64Cls(TransactionType.AssetFreeze).toBytes().asAlgoTs() } export type ApplicationTransactionFields = TxnFields & @@ -260,10 +262,10 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl return Uint64(this.#apps.length) } get numApprovalProgramPages() { - return Uint64(this.#approvalProgramPages.length) + return Uint64(this.approvalProgramPages.length) } get numClearStateProgramPages() { - return Uint64(this.#clearStateProgramPages.length) + return Uint64(this.clearStateProgramPages.length) } get numLogs() { return Uint64(this.#appLogs.length || lazyContext.getApplicationData(this.appId.id).appLogs.length) @@ -284,16 +286,17 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl return this.#apps[asNumber(index)] } approvalProgramPages(index: internal.primitives.StubUint64Compat): bytes { - return this.#approvalProgramPages[asNumber(index)] + return combineIntoMaxBytePages(this.#approvalProgramPages)[asNumber(index)] } clearStateProgramPages(index: internal.primitives.StubUint64Compat): bytes { - return this.#clearStateProgramPages[asNumber(index)] + return combineIntoMaxBytePages(this.#clearStateProgramPages)[asNumber(index)] } logs(index: internal.primitives.StubUint64Compat): bytes { const i = asNumber(index) return this.#appLogs[i] ?? lazyContext.getApplicationData(this.appId.id).appLogs ?? Bytes() } readonly type: TransactionType.ApplicationCall = TransactionType.ApplicationCall + readonly typeBytes: bytes = asUint64Cls(TransactionType.ApplicationCall).toBytes().asAlgoTs() /* @internal */ get appLogs() { diff --git a/src/impl/txn.ts b/src/impl/txn.ts index 6d8c434..2709a54 100644 --- a/src/impl/txn.ts +++ b/src/impl/txn.ts @@ -1,10 +1,15 @@ -import { Account, Application, arc4, Asset, bytes, gtxn, internal, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, arc4, Asset, bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algo-ts' import { lazyContext } from '../context-helpers/internal-context' import { asNumber, asUint64, asUint64Cls } from '../util' - -const getActiveTransaction = (): T => { - return lazyContext.activeGroup.activeTransaction as T -} +// import { +// getApplicationTransaction, +// getAssetConfigTransaction, +// getAssetFreezeTransaction, +// getAssetTransferTransaction, +// getKeyRegistrationTransaction, +// getPaymentTransaction, +// getTransaction, +// } from './gtxn' export const gaid = (a: internal.primitives.StubUint64Compat): uint64 => { const group = lazyContext.activeGroup @@ -20,182 +25,182 @@ export const gaid = (a: internal.primitives.StubUint64Compat): uint64 => { export const Txn: internal.opTypes.TxnType = { get sender(): Account { - return getActiveTransaction().sender + return lazyContext.activeGroup.getTransaction().sender }, /** * microalgos */ get fee(): uint64 { - return getActiveTransaction().fee + return lazyContext.activeGroup.getTransaction().fee }, /** * round number */ get firstValid(): uint64 { - return getActiveTransaction().firstValid + return lazyContext.activeGroup.getTransaction().firstValid }, /** * UNIX timestamp of block before txn.FirstValid. Fails if negative */ get firstValidTime(): uint64 { - return getActiveTransaction().firstValidTime + return lazyContext.activeGroup.getTransaction().firstValidTime }, /** * round number */ get lastValid(): uint64 { - return getActiveTransaction().lastValid + return lazyContext.activeGroup.getTransaction().lastValid }, /** * Any data up to 1024 bytes */ get note(): bytes { - return getActiveTransaction().note + return lazyContext.activeGroup.getTransaction().note }, /** * 32 byte lease value */ get lease(): bytes { - return getActiveTransaction().lease + return lazyContext.activeGroup.getTransaction().lease }, /** * 32 byte address */ get receiver(): Account { - return getActiveTransaction().receiver + return lazyContext.activeGroup.getPaymentTransaction().receiver }, /** * microalgos */ get amount(): uint64 { - return getActiveTransaction().amount + return lazyContext.activeGroup.getPaymentTransaction().amount }, /** * 32 byte address */ get closeRemainderTo(): Account { - return getActiveTransaction().closeRemainderTo + return lazyContext.activeGroup.getPaymentTransaction().closeRemainderTo }, /** * 32 byte address */ get votePk(): bytes { - return getActiveTransaction().voteKey + return lazyContext.activeGroup.getKeyRegistrationTransaction().voteKey }, /** * 32 byte address */ get selectionPk(): bytes { - return getActiveTransaction().selectionKey + return lazyContext.activeGroup.getKeyRegistrationTransaction().selectionKey }, /** * The first round that the participation key is valid. */ get voteFirst(): uint64 { - return getActiveTransaction().voteFirst + return lazyContext.activeGroup.getKeyRegistrationTransaction().voteFirst }, /** * The last round that the participation key is valid. */ get voteLast(): uint64 { - return getActiveTransaction().voteLast + return lazyContext.activeGroup.getKeyRegistrationTransaction().voteLast }, /** * Dilution for the 2-level participation key */ get voteKeyDilution(): uint64 { - return getActiveTransaction().voteKeyDilution + return lazyContext.activeGroup.getKeyRegistrationTransaction().voteKeyDilution }, /** * Transaction type as bytes */ get type(): bytes { - return asUint64Cls(getActiveTransaction().type).toBytes().asAlgoTs() + return asUint64Cls(lazyContext.activeGroup.getTransaction().type).toBytes().asAlgoTs() }, /** * Transaction type as integer */ get typeEnum(): uint64 { - return asUint64(getActiveTransaction().type) + return asUint64(lazyContext.activeGroup.getTransaction().type) }, /** * Asset ID */ get xferAsset(): Asset { - return getActiveTransaction().xferAsset + return lazyContext.activeGroup.getAssetTransferTransaction().xferAsset }, /** * value in Asset's units */ get assetAmount(): uint64 { - return getActiveTransaction().assetAmount + return lazyContext.activeGroup.getAssetTransferTransaction().assetAmount }, /** * 32 byte address. Source of assets if Sender is the Asset's Clawback address. */ get assetSender(): Account { - return getActiveTransaction().assetSender + return lazyContext.activeGroup.getAssetTransferTransaction().assetSender }, /** * 32 byte address */ get assetReceiver(): Account { - return getActiveTransaction().assetReceiver + return lazyContext.activeGroup.getAssetTransferTransaction().assetReceiver }, /** * 32 byte address */ get assetCloseTo(): Account { - return getActiveTransaction().assetCloseTo + return lazyContext.activeGroup.getAssetTransferTransaction().assetCloseTo }, /** * Position of this transaction within an atomic transaction group. A stand-alone transaction is implicitly element 0 in a group of 1 */ get groupIndex(): uint64 { - return getActiveTransaction().groupIndex + return lazyContext.activeGroup.getTransaction().groupIndex }, /** * The computed ID for this transaction. 32 bytes. */ get txId(): bytes { - return getActiveTransaction().txnId + return lazyContext.activeGroup.getTransaction().txnId }, /** * ApplicationID from ApplicationCall transaction */ get applicationId(): Application { - return getActiveTransaction().appId + return lazyContext.activeGroup.getApplicationTransaction().appId }, /** * ApplicationCall transaction on completion action */ get onCompletion(): uint64 { - const onCompletionStr = getActiveTransaction().onCompletion + const onCompletionStr = lazyContext.activeGroup.getApplicationTransaction().onCompletion return asUint64(arc4.OnCompleteAction[onCompletionStr]) }, @@ -203,293 +208,293 @@ export const Txn: internal.opTypes.TxnType = { * Arguments passed to the application in the ApplicationCall transaction */ applicationArgs(a: internal.primitives.StubUint64Compat): bytes { - return getActiveTransaction().appArgs(asUint64(a)) + return lazyContext.activeGroup.getApplicationTransaction().appArgs(asUint64(a)) }, /** * Number of ApplicationArgs */ get numAppArgs(): uint64 { - return getActiveTransaction().numAppArgs + return lazyContext.activeGroup.getApplicationTransaction().numAppArgs }, /** * Accounts listed in the ApplicationCall transaction */ accounts(a: internal.primitives.StubUint64Compat): Account { - return getActiveTransaction().accounts(asUint64(a)) + return lazyContext.activeGroup.getApplicationTransaction().accounts(asUint64(a)) }, /** * Number of Accounts */ get numAccounts(): uint64 { - return getActiveTransaction().numAccounts + return lazyContext.activeGroup.getApplicationTransaction().numAccounts }, /** * Approval program */ get approvalProgram(): bytes { - return getActiveTransaction().approvalProgram + return lazyContext.activeGroup.getApplicationTransaction().approvalProgram }, /** * Clear state program */ get clearStateProgram(): bytes { - return getActiveTransaction().clearStateProgram + return lazyContext.activeGroup.getApplicationTransaction().clearStateProgram }, /** * 32 byte Sender's new AuthAddr */ get rekeyTo(): Account { - return getActiveTransaction().rekeyTo + return lazyContext.activeGroup.getTransaction().rekeyTo }, /** * Asset ID in asset config transaction */ get configAsset(): Asset { - return getActiveTransaction().configAsset + return lazyContext.activeGroup.getAssetConfigTransaction().configAsset }, /** * Total number of units of this asset created */ get configAssetTotal(): uint64 { - return getActiveTransaction().total + return lazyContext.activeGroup.getAssetConfigTransaction().total }, /** * Number of digits to display after the decimal place when displaying the asset */ get configAssetDecimals(): uint64 { - return getActiveTransaction().decimals + return lazyContext.activeGroup.getAssetConfigTransaction().decimals }, /** * Whether the asset's slots are frozen by default or not, 0 or 1 */ get configAssetDefaultFrozen(): boolean { - return getActiveTransaction().defaultFrozen + return lazyContext.activeGroup.getAssetConfigTransaction().defaultFrozen }, /** * Unit name of the asset */ get configAssetUnitName(): bytes { - return getActiveTransaction().unitName + return lazyContext.activeGroup.getAssetConfigTransaction().unitName }, /** * The asset name */ get configAssetName(): bytes { - return getActiveTransaction().assetName + return lazyContext.activeGroup.getAssetConfigTransaction().assetName }, /** * URL */ get configAssetUrl(): bytes { - return getActiveTransaction().url + return lazyContext.activeGroup.getAssetConfigTransaction().url }, /** * 32 byte commitment to unspecified asset metadata */ get configAssetMetadataHash(): bytes { - return getActiveTransaction().metadataHash + return lazyContext.activeGroup.getAssetConfigTransaction().metadataHash }, /** * 32 byte address */ get configAssetManager(): Account { - return getActiveTransaction().manager + return lazyContext.activeGroup.getAssetConfigTransaction().manager }, /** * 32 byte address */ get configAssetReserve(): Account { - return getActiveTransaction().reserve + return lazyContext.activeGroup.getAssetConfigTransaction().reserve }, /** * 32 byte address */ get configAssetFreeze(): Account { - return getActiveTransaction().freeze + return lazyContext.activeGroup.getAssetConfigTransaction().freeze }, /** * 32 byte address */ get configAssetClawback(): Account { - return getActiveTransaction().clawback + return lazyContext.activeGroup.getAssetConfigTransaction().clawback }, /** * Asset ID being frozen or un-frozen */ get freezeAsset(): Asset { - return getActiveTransaction().freezeAsset + return lazyContext.activeGroup.getAssetFreezeTransaction().freezeAsset }, /** * 32 byte address of the account whose asset slot is being frozen or un-frozen */ get freezeAssetAccount(): Account { - return getActiveTransaction().freezeAccount + return lazyContext.activeGroup.getAssetFreezeTransaction().freezeAccount }, /** * The new frozen value, 0 or 1 */ get freezeAssetFrozen(): boolean { - return getActiveTransaction().frozen + return lazyContext.activeGroup.getAssetFreezeTransaction().frozen }, /** * Foreign Assets listed in the ApplicationCall transaction */ assets(a: internal.primitives.StubUint64Compat): Asset { - return getActiveTransaction().assets(asUint64(a)) + return lazyContext.activeGroup.getApplicationTransaction().assets(asUint64(a)) }, /** * Number of Assets */ get numAssets(): uint64 { - return getActiveTransaction().numAssets + return lazyContext.activeGroup.getApplicationTransaction().numAssets }, /** * Foreign Apps listed in the ApplicationCall transaction */ applications(a: internal.primitives.StubUint64Compat): Application { - return getActiveTransaction().apps(asUint64(a)) + return lazyContext.activeGroup.getApplicationTransaction().apps(asUint64(a)) }, /** * Number of Applications */ get numApplications(): uint64 { - return getActiveTransaction().numApps + return lazyContext.activeGroup.getApplicationTransaction().numApps }, /** * Number of global state integers in ApplicationCall */ get globalNumUint(): uint64 { - return getActiveTransaction().globalNumUint + return lazyContext.activeGroup.getApplicationTransaction().globalNumUint }, /** * Number of global state byteslices in ApplicationCall */ get globalNumByteSlice(): uint64 { - return getActiveTransaction().globalNumBytes + return lazyContext.activeGroup.getApplicationTransaction().globalNumBytes }, /** * Number of local state integers in ApplicationCall */ get localNumUint(): uint64 { - return getActiveTransaction().localNumUint + return lazyContext.activeGroup.getApplicationTransaction().localNumUint }, /** * Number of local state byteslices in ApplicationCall */ get localNumByteSlice(): uint64 { - return getActiveTransaction().localNumBytes + return lazyContext.activeGroup.getApplicationTransaction().localNumBytes }, /** * Number of additional pages for each of the application's approval and clear state programs. An ExtraProgramPages of 1 means 2048 more total bytes, or 1024 for each program. */ get extraProgramPages(): uint64 { - return getActiveTransaction().extraProgramPages + return lazyContext.activeGroup.getApplicationTransaction().extraProgramPages }, /** * Marks an account nonparticipating for rewards */ get nonparticipation(): boolean { - return getActiveTransaction().nonparticipation + return lazyContext.activeGroup.getKeyRegistrationTransaction().nonparticipation }, /** * Log messages emitted by an application call (only with `itxn` in v5). Application mode only */ logs(a: internal.primitives.StubUint64Compat): bytes { - return getActiveTransaction().logs(asUint64(a)) + return lazyContext.activeGroup.getApplicationTransaction().logs(asUint64(a)) }, /** * Number of Logs (only with `itxn` in v5). Application mode only */ get numLogs(): uint64 { - return getActiveTransaction().numLogs + return lazyContext.activeGroup.getApplicationTransaction().numLogs }, /** * Asset ID allocated by the creation of an ASA (only with `itxn` in v5). Application mode only */ get createdAssetId(): Asset { - return getActiveTransaction().createdAsset + return lazyContext.activeGroup.getAssetConfigTransaction().createdAsset }, /** * ApplicationID allocated by the creation of an application (only with `itxn` in v5). Application mode only */ get createdApplicationId(): Application { - return getActiveTransaction().createdApp + return lazyContext.activeGroup.getApplicationTransaction().createdApp }, /** * The last message emitted. Empty bytes if none were emitted. Application mode only */ get lastLog(): bytes { - return getActiveTransaction().lastLog + return lazyContext.activeGroup.getApplicationTransaction().lastLog }, /** * 64 byte state proof public key */ get stateProofPk(): bytes { - return getActiveTransaction().stateProofKey + return lazyContext.activeGroup.getKeyRegistrationTransaction().stateProofKey }, /** * Approval Program as an array of pages */ approvalProgramPages(a: internal.primitives.StubUint64Compat): bytes { - return getActiveTransaction().approvalProgramPages(asUint64(a)) + return lazyContext.activeGroup.getApplicationTransaction().approvalProgramPages(asUint64(a)) }, /** * Number of Approval Program pages */ get numApprovalProgramPages(): uint64 { - return getActiveTransaction().numApprovalProgramPages + return lazyContext.activeGroup.getApplicationTransaction().numApprovalProgramPages }, /** * ClearState Program as an array of pages */ clearStateProgramPages(a: internal.primitives.StubUint64Compat): bytes { - return getActiveTransaction().clearStateProgramPages(asUint64(a)) + return lazyContext.activeGroup.getApplicationTransaction().clearStateProgramPages(asUint64(a)) }, /** * Number of ClearState Program pages */ get numClearStateProgramPages(): uint64 { - return getActiveTransaction().numClearStateProgramPages + return lazyContext.activeGroup.getApplicationTransaction().numClearStateProgramPages }, } diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index a57c111..928e598 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -3,10 +3,27 @@ import algosdk from 'algosdk' import { lazyContext } from '../context-helpers/internal-context' import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' import { testInvariant } from '../errors' -import { AllTransactionFields, Transaction } from '../impl/transactions' -import { asBigInt, asUint64 } from '../util' +import { + AllTransactionFields, + ApplicationTransaction, + AssetConfigTransaction, + AssetFreezeTransaction, + AssetTransferTransaction, + KeyRegistrationTransaction, + PaymentTransaction, + Transaction, +} from '../impl/transactions' +import { asBigInt, asNumber, asUint64 } from '../util' import { InnerTxn, InnerTxnFields } from '../impl/itxn' -import { createInnerTxn } from '../impl/inner-transactions' +import { + ApplicationInnerTxn, + AssetConfigInnerTxn, + AssetFreezeInnerTxn, + AssetTransferInnerTxn, + createInnerTxn, + KeyRegistrationInnerTxn, + PaymentInnerTxn, +} from '../impl/inner-transactions' function ScopeGenerator(dispose: () => void) { function* internal() { @@ -111,7 +128,7 @@ export class TransactionGroup { activeTransactionIndex: number latestTimestamp: number transactions: Transaction[] - itxnGroups: InnerTxn[][] = [] + itxnGroups: ItxnGroup[] = [] constructingItxnGroup: InnerTxnFields[] = [] constructor(transactions: Transaction[], activeTransactionIndex?: number) { @@ -162,7 +179,7 @@ export class TransactionGroup { this.constructingItxnGroup.push({} as InnerTxnFields) } - appendInnterTransactionGroup() { + appendInnerTransactionGroup() { if (!this.constructingItxnGroup.length) { internal.errors.internalError('itxn next without itxn begin') } @@ -178,7 +195,130 @@ export class TransactionGroup { } const itxns = this.constructingItxnGroup.map((t) => createInnerTxn(t)) itxns.forEach((itxn, index) => Object.assign(itxn, { groupIndex: asUint64(index) })) - this.itxnGroups.push(itxns) + this.itxnGroups.push(new ItxnGroup(itxns)) this.constructingItxnGroup = [] } + + getItxnGroup(index?: internal.primitives.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') + } + 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 { + return this.getTransactionImpl({ type: TransactionType.ApplicationCall, index }) as ApplicationTransaction + } + getAssetConfigTransaction(index?: internal.primitives.StubUint64Compat): AssetConfigTransaction { + return this.getTransactionImpl({ type: TransactionType.AssetConfig, index }) as AssetConfigTransaction + } + getAssetTransferTransaction(index?: internal.primitives.StubUint64Compat): AssetTransferTransaction { + return this.getTransactionImpl({ type: TransactionType.AssetTransfer, index }) as AssetTransferTransaction + } + getAssetFreezeTransaction(index?: internal.primitives.StubUint64Compat): AssetFreezeTransaction { + return this.getTransactionImpl({ type: TransactionType.AssetFreeze, index }) as AssetFreezeTransaction + } + getKeyRegistrationTransaction(index?: internal.primitives.StubUint64Compat): KeyRegistrationTransaction { + return this.getTransactionImpl({ type: TransactionType.KeyRegistration, index }) as KeyRegistrationTransaction + } + getPaymentTransaction(index?: internal.primitives.StubUint64Compat): PaymentTransaction { + return this.getTransactionImpl({ type: TransactionType.Payment, index }) as PaymentTransaction + } + getTransaction(index?: internal.primitives.StubUint64Compat): Transaction { + return this.getTransactionImpl({ index }) + } + private getTransactionImpl({ type, index }: { type?: TransactionType; index?: internal.primitives.StubUint64Compat }) { + const i = index !== undefined ? asNumber(index) : undefined + if (i !== undefined && i >= lazyContext.activeGroup.transactions.length) { + throw new internal.errors.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}`) + } + switch (type) { + case TransactionType.ApplicationCall: + return transaction as ApplicationTransaction + case TransactionType.Payment: + return transaction as PaymentTransaction + case TransactionType.AssetConfig: + return transaction as AssetConfigTransaction + case TransactionType.AssetTransfer: + return transaction as AssetTransferTransaction + case TransactionType.AssetFreeze: + return transaction as AssetFreezeTransaction + case TransactionType.KeyRegistration: + return transaction as KeyRegistrationTransaction + default: + throw new internal.errors.InternalError(`Invalid transaction type: ${type}`) + } + } +} + +export class ItxnGroup { + itxns: InnerTxn[] = [] + constructor(itxns: InnerTxn[]) { + this.itxns = itxns + } + + getApplicationInnerTxn(index?: internal.primitives.StubUint64Compat): ApplicationInnerTxn { + return this.getInnerTxnImpl({ type: TransactionType.ApplicationCall, index }) as ApplicationInnerTxn + } + getAssetConfigInnerTxn(index?: internal.primitives.StubUint64Compat): AssetConfigInnerTxn { + return this.getInnerTxnImpl({ type: TransactionType.AssetConfig, index }) as AssetConfigInnerTxn + } + getAssetTransferInnerTxn(index?: internal.primitives.StubUint64Compat): AssetTransferInnerTxn { + return this.getInnerTxnImpl({ type: TransactionType.AssetTransfer, index }) as AssetTransferInnerTxn + } + getAssetFreezeInnerTxn(index?: internal.primitives.StubUint64Compat): AssetFreezeInnerTxn { + return this.getInnerTxnImpl({ type: TransactionType.AssetFreeze, index }) as AssetFreezeInnerTxn + } + getKeyRegistrationInnerTxn(index?: internal.primitives.StubUint64Compat): KeyRegistrationInnerTxn { + return this.getInnerTxnImpl({ type: TransactionType.KeyRegistration, index }) as KeyRegistrationInnerTxn + } + getPaymentInnerTxn(index?: internal.primitives.StubUint64Compat): PaymentInnerTxn { + return this.getInnerTxnImpl({ type: TransactionType.Payment, index }) as PaymentInnerTxn + } + getInnerTxn(index?: internal.primitives.StubUint64Compat): InnerTxn { + return this.getInnerTxnImpl({ index }) + } + + private getInnerTxnImpl({ type, index }: { type?: TransactionType; index?: internal.primitives.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') + } + 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}`) + } + switch (type) { + case TransactionType.ApplicationCall: + return transaction as ApplicationInnerTxn + case TransactionType.Payment: + return transaction as PaymentInnerTxn + case TransactionType.AssetConfig: + return transaction as AssetConfigInnerTxn + case TransactionType.AssetTransfer: + return transaction as AssetTransferInnerTxn + case TransactionType.AssetFreeze: + return transaction as AssetFreezeInnerTxn + case TransactionType.KeyRegistration: + return transaction as KeyRegistrationInnerTxn + default: + throw new internal.errors.InternalError(`Invalid transaction type: ${type}`) + } + } } diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index b53cb69..33bf396 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -10,15 +10,6 @@ import { ContractContext } from './subcontexts/contract-context' import { LedgerContext } from './subcontexts/ledger-context' import { TransactionContext } from './subcontexts/transaction-context' import { ValueGenerator } from './value-generators' -import { - getApplicationTransaction, - getAssetConfigTransaction, - getAssetFreezeTransaction, - getAssetTransferTransaction, - getKeyRegistrationTransaction, - getPaymentTransaction, - getTransaction, -} from './impl/gtxn' export class TestExecutionContext implements internal.ExecutionContext { #applicationLogs: Map @@ -89,13 +80,13 @@ export class TestExecutionContext implements internal.ExecutionContext { get gtxn() { return { - Transaction: (index: uint64) => getTransaction(index), - PaymentTxn: (index: uint64) => getPaymentTransaction(index), - KeyRegistrationTxn: (index: uint64) => getKeyRegistrationTransaction(index), - AssetConfigTxn: (index: uint64) => getAssetConfigTransaction(index), - AssetTransferTxn: (index: uint64) => getAssetTransferTransaction(index), - AssetFreezeTxn: (index: uint64) => getAssetFreezeTransaction(index), - ApplicationTxn: (index: uint64) => getApplicationTransaction(index), + 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), } } diff --git a/src/util.ts b/src/util.ts index f059fcb..6f3a108 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,6 +1,6 @@ import { internal, bytes } from '@algorandfoundation/algo-ts' import { randomBytes } from 'crypto' -import { BITS_IN_BYTE, MAX_UINT512, MAX_UINT8, UINT512_SIZE } from './constants' +import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT8, UINT512_SIZE } from './constants' import { DeliberateAny } from './typescript-helpers' export const nameOfType = (x: unknown) => { @@ -148,3 +148,16 @@ export const getObjectReference = (obj: DeliberateAny): bigint => { return ref } + +export const combineIntoMaxBytePages = (pages: bytes[]): bytes[] => { + const combined = pages.reduce((acc, x) => acc.concat(x), asBytesCls('')) + const totalPages = (asNumber(combined.length) + MAX_BYTES_SIZE - 1) / MAX_BYTES_SIZE + const result = [] as bytes[] + for (let i = 0; i < totalPages; i++) { + const start = i * MAX_BYTES_SIZE + const end = Math.min((i + 1) * MAX_BYTES_SIZE, asNumber(combined.length)) + const page = combined.slice(start, end) + result.push(page.asAlgoTs()) + } + return result +} diff --git a/tests/artifacts/state-ops/contract.algo.ts b/tests/artifacts/state-ops/contract.algo.ts index 2d52f85..739cb58 100644 --- a/tests/artifacts/state-ops/contract.algo.ts +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -1,4 +1,17 @@ -import { Account, Application, arc4, assert, Asset, bytes, op, Txn, uint64 } from '@algorandfoundation/algo-ts' +import { + Account, + Application, + arc4, + assert, + Asset, + Bytes, + bytes, + op, + TransactionType, + Txn, + Uint64, + uint64, +} from '@algorandfoundation/algo-ts' function get_1st_ref_index(): uint64 { return op.btoi(Txn.applicationArgs(1)) @@ -335,3 +348,30 @@ export class StateAppParamsContract extends arc4.Contract { return value } } + +export class ITxnOpsContract extends arc4.Contract { + @arc4.abimethod() + public verify_itxn_ops() { + op.ITxnCreate.begin() + op.ITxnCreate.setTypeEnum(TransactionType.ApplicationCall) + op.ITxnCreate.setOnCompletion(arc4.OnCompleteAction.DeleteApplication) + op.ITxnCreate.setApprovalProgram(Bytes.fromHex('068101')) + + // pages essentially appends + op.ITxnCreate.setApprovalProgramPages(Bytes.fromHex('068101')) + op.ITxnCreate.setClearStateProgram(Bytes.fromHex('068101')) + op.ITxnCreate.setFee(op.Global.minTxnFee) + op.ITxnCreate.next() + op.ITxnCreate.setTypeEnum(TransactionType.Payment) + op.ITxnCreate.setReceiver(op.Global.creatorAddress) + op.ITxnCreate.setAmount(Uint64(1000)) + op.ITxnCreate.submit() + + assert(op.ITxn.receiver === op.Global.creatorAddress) + assert(op.ITxn.amount === Uint64(1000)) + assert(op.ITxn.typeEnum === TransactionType.Payment) + + assert(op.GITxn.typeEnum(0) == TransactionType.ApplicationCall) + assert(op.GITxn.typeEnum(1) == TransactionType.Payment) + } +} diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 3f44326..f00504b 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -1,4 +1,4 @@ -import { Account, bytes, Bytes, internal, op, uint64, Uint64 } from '@algorandfoundation/algo-ts' +import { Account, arc4, bytes, Bytes, internal, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algo-ts' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' @@ -13,11 +13,12 @@ import { } from './avm-invoker' import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' -import { ZERO_ADDRESS } from '../src/constants' +import { MIN_TXN_FEE, ZERO_ADDRESS } from '../src/constants' import { AccountCls } from '../src/impl/account' -import { asBigInt, asNumber } from '../src/util' +import { asBigInt, asNumber, asUint64Cls } from '../src/util' import { AppExpectingEffects } from './artifacts/created-app-asset/contract.algo' import { + ITxnOpsContract, StateAcctParamsGetContract, StateAppParamsContract, StateAssetHoldingContract, @@ -28,6 +29,8 @@ import appParamsAppSpecJson from './artifacts/state-ops/data/StateAppParamsContr import assetHoldingAppSpecJson from './artifacts/state-ops/data/StateAssetHoldingContract.arc32.json' import assetParamsAppSpecJson from './artifacts/state-ops/data/StateAssetParamsContract.arc32.json' import { asUint8Array } from './util' +import { InnerTxn } from '../src/impl/itxn' +import { ApplicationTransaction } from '../src/impl/transactions' describe('State op codes', async () => { const ctx = new TestExecutionContext() @@ -258,7 +261,7 @@ describe('State op codes', async () => { expect(op.Global.callerApplicationId.valueOf()).toEqual(caller.id.valueOf()) expect(op.Global.callerApplicationAddress).toEqual(caller.address) }) - expect(asUint8Array(firstGroupId)).not.toEqual(asUint8Array(secondGroupId)) + expect([...asUint8Array(firstGroupId)]).not.toEqual([...asUint8Array(secondGroupId)]) expect(firstTimestamp.valueOf()).not.toEqual(secondTimestamp.valueOf()) }) }) @@ -296,4 +299,61 @@ describe('State op codes', async () => { // contract.log_group(appCallTxn) // }) }) + + describe('itxn', async () => { + it('should return the correct field value of the transaction', async () => { + // arrange + const contract = ctx.contract.create(ITxnOpsContract) + + // act + contract.verify_itxn_ops() + + // assert + const itxnGroup = ctx.txn.lastGroup.getItxnGroup(0) + const appItxn = itxnGroup.getApplicationInnerTxn(0) + const paymentItxn = itxnGroup.getPaymentInnerTxn(1) + + // Test application call transaction fields + expect([...asUint8Array(appItxn.approvalProgram)]).toEqual([...asUint8Array(Bytes.fromHex('068101068101'))]) + expect([...asUint8Array(appItxn.clearStateProgram)]).toEqual([...asUint8Array(Bytes.fromHex('068101'))]) + const approvalPages = Array(asNumber(appItxn.numApprovalProgramPages)) + .fill(0) + .map((_, i) => [...asUint8Array(appItxn.approvalProgramPages(i))]) + expect(approvalPages).toEqual([[...asUint8Array(appItxn.approvalProgram)]]) + expect(appItxn.onCompletion).toEqual(arc4.OnCompleteAction[arc4.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 + // in unit testing context (vs integration tests)? + // considering we don't emulate balance (transfer, accounting for fees and etc) + expect(asNumber(appItxn.appId.id)).toEqual(0) + expect(appItxn.type).toEqual(TransactionType.ApplicationCall) + expect(appItxn.typeBytes).toEqual(asUint64Cls(TransactionType.ApplicationCall).toBytes()) + + // Test payment transaction fields + expect(paymentItxn.receiver).toEqual(ctx.defaultSender) + expect(asNumber(paymentItxn.amount)).toEqual(1000) + expect(paymentItxn.sender).toEqual(ctx.ledger.getApplicationForContract(contract).address) + expect(paymentItxn.type).toEqual(TransactionType.Payment) + expect(appItxn.typeBytes).toEqual(asUint64Cls(TransactionType.Payment).toBytes()) + + // 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) + }) + + // Test logs (should be empty for newly created transactions as its a void method) + expect(asNumber((ctx.txn.lastActive as ApplicationTransaction).numLogs)).toEqual(0) + expect((ctx.txn.lastActive as ApplicationTransaction).lastLog).toEqual(Bytes('')) + + // Test created_app and created_asset (should be created for these transactions) + expect(appItxn.createdApp).toBeTruthy() + }) + }) }) From d13f0e0f99a9124029f9f1c6540725cfc51f39e2 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 1 Oct 2024 13:48:48 +0800 Subject: [PATCH 06/85] implement functions to create itxn and add tests for those --- src/impl/inner-transactions.ts | 68 +++++++++++++-- src/subcontexts/transaction-context.ts | 2 +- src/test-execution-context.ts | 21 +++++ tests/artifacts/state-ops/contract.algo.ts | 99 ++++++++++++++++++++++ tests/state-op-codes.spec.ts | 13 ++- 5 files changed, 193 insertions(+), 10 deletions(-) diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts index 93933d1..893b088 100644 --- a/src/impl/inner-transactions.ts +++ b/src/impl/inner-transactions.ts @@ -158,21 +158,73 @@ export class ApplicationInnerTxn extends ApplicationTransaction implements itxn. } } -export const createInnerTxn = (fields: InnerTxnFields): InnerTxn => { +export const createInnerTxn = (fields: TFields): T => { switch (fields.type) { case TransactionType.Payment: - return new PaymentInnerTxn(fields) + return new PaymentInnerTxn(fields) as T case TransactionType.AssetConfig: - return new AssetConfigInnerTxn(fields) + return new AssetConfigInnerTxn(fields) as T case TransactionType.AssetTransfer: - return new AssetTransferInnerTxn(fields as itxn.AssetTransferFields) + return new AssetTransferInnerTxn(fields as itxn.AssetTransferFields) as T case TransactionType.AssetFreeze: - return new AssetFreezeInnerTxn(fields as itxn.AssetFreezeFields) + return new AssetFreezeInnerTxn(fields as itxn.AssetFreezeFields) as T case TransactionType.ApplicationCall: - return new ApplicationInnerTxn(fields) + return new ApplicationInnerTxn(fields) as unknown as T case TransactionType.KeyRegistration: - return new KeyRegistrationInnerTxn(fields) + return new KeyRegistrationInnerTxn(fields) as T default: - internal.errors.internalError(`Invalid inner transaction type: ${fields.type}`) + throw new internal.errors.InternalError(`Invalid inner transaction type: ${fields.type}`) + } +} + +export function submitGroup(...transactionFields: TFields): itxn.TxnFor { + return transactionFields.map((f: (typeof transactionFields)[number]) => f.submit()) as itxn.TxnFor +} +export function payment(fields: itxn.PaymentFields): itxn.PaymentItxnParams { + ensureItxnGroupBegin() + return new ItxnParams(fields, TransactionType.Payment) +} +export function keyRegistration(fields: itxn.KeyRegistrationFields): itxn.KeyRegistrationItxnParams { + ensureItxnGroupBegin() + return new ItxnParams(fields, TransactionType.KeyRegistration) +} +export function assetConfig(fields: itxn.AssetConfigFields): itxn.AssetConfigItxnParams { + ensureItxnGroupBegin() + return new ItxnParams(fields, TransactionType.AssetConfig) +} +export function assetTransfer(fields: itxn.AssetTransferFields): itxn.AssetTransferItxnParams { + ensureItxnGroupBegin() + return new ItxnParams(fields, TransactionType.AssetTransfer) +} +export function assetFreeze(fields: itxn.AssetFreezeFields): itxn.AssetFreezeItxnParams { + ensureItxnGroupBegin() + return new ItxnParams(fields, TransactionType.AssetFreeze) +} +export function applicationCall(fields: itxn.ApplicationCallFields): itxn.ApplicationCallItxnParams { + ensureItxnGroupBegin() + return new ItxnParams(fields, TransactionType.ApplicationCall) +} + +export class ItxnParams { + #fields: TFields & { type: TransactionType } + constructor(fields: TFields, type: TransactionType) { + this.#fields = { ...fields, type } + } + submit(): TTransaction { + return createInnerTxn(this.#fields) + } + + set(p: Partial) { + Object.assign(this.#fields, p) + } + + copy() { + return new ItxnParams(this.#fields, this.#fields.type) + } +} + +const ensureItxnGroupBegin = () => { + if (!lazyContext.activeGroup.constructingItxnGroup.length) { + lazyContext.activeGroup.beginInnerTransactionGroup() } } diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 928e598..529eee4 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -183,7 +183,7 @@ export class TransactionGroup { if (!this.constructingItxnGroup.length) { internal.errors.internalError('itxn next without itxn begin') } - this.constructingItxnGroup.push({} as InnerTxnFields) + this.constructingItxnGroup.push({ type: TransactionType.Payment } as InnerTxnFields) } submitInnerTransactionGroup() { diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 33bf396..5cc9d09 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -10,6 +10,15 @@ import { ContractContext } from './subcontexts/contract-context' import { LedgerContext } from './subcontexts/ledger-context' import { TransactionContext } from './subcontexts/transaction-context' import { ValueGenerator } from './value-generators' +import { + submitGroup as itxnSubmitGroup, + payment as itxnPayment, + keyRegistration as itxnKeyRegistration, + assetConfig as itxnAssetConfig, + assetTransfer as itxnAssetTransfer, + assetFreeze as itxnAssetFreeze, + applicationCall as itxnApplicationCall, +} from './impl/inner-transactions' export class TestExecutionContext implements internal.ExecutionContext { #applicationLogs: Map @@ -90,6 +99,18 @@ export class TestExecutionContext implements internal.ExecutionContext { } } + get itxn() { + return { + submitGroup: itxnSubmitGroup, + payment: itxnPayment, + keyRegistration: itxnKeyRegistration, + assetConfig: itxnAssetConfig, + assetTransfer: itxnAssetTransfer, + assetFreeze: itxnAssetFreeze, + applicationCall: itxnApplicationCall, + } + } + reset() { this.#applicationLogs.clear() this.#contractContext = new ContractContext() diff --git a/tests/artifacts/state-ops/contract.algo.ts b/tests/artifacts/state-ops/contract.algo.ts index 739cb58..698beee 100644 --- a/tests/artifacts/state-ops/contract.algo.ts +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -4,8 +4,12 @@ import { arc4, assert, Asset, + BaseContract, Bytes, bytes, + Global, + GlobalState, + itxn, op, TransactionType, Txn, @@ -375,3 +379,98 @@ export class ITxnOpsContract extends arc4.Contract { assert(op.GITxn.typeEnum(1) == TransactionType.Payment) } } + +const APPROVE = Bytes('\x09\x81\x01') +export class ItxnDemoContract extends BaseContract { + name = GlobalState({ initialValue: Bytes() }) + + public approvalProgram(): boolean { + if (Txn.numAppArgs) { + switch (Txn.applicationArgs(0)) { + case Bytes('test1'): + this.test1() + break + case Bytes('test2'): + this.test2() + break + case Bytes('test3'): + case Bytes('test4'): + break + } + } + return true + } + + private test1() { + this.name.value = Bytes('AST1') + + const assetParams = itxn.assetConfig({ + total: 1000, + assetName: this.name.value, + unitName: 'unit', + decimals: 3, + manager: Global.currentApplicationAddress, + reserve: Global.currentApplicationAddress, + }) + + this.name.value = Bytes('AST2') + const asset1_txn = assetParams.submit() + assetParams.set({ + assetName: this.name.value, + }) + const asset2_txn = assetParams.submit() + + assert(asset1_txn.assetName === Bytes('AST1'), 'asset1_txn is correct') + assert(asset2_txn.assetName === Bytes('AST2'), 'asset2_txn is correct') + assert(asset1_txn.createdAsset.name === Bytes('AST1'), 'created asset 1 is correct') + assert(asset2_txn.createdAsset.name === Bytes('AST2'), 'created asset 2 is correct') + + const appCreateParams = itxn.applicationCall({ + approvalProgram: Bytes.fromHex('098101'), + clearStateProgram: Bytes.fromHex('098101'), + fee: 0, + }) + + assetParams.set({ + assetName: 'AST3', + }) + + const [appCreateTxn, asset3_txn] = itxn.submitGroup(appCreateParams, assetParams) + + assert(appCreateTxn.appId, 'app is created') + assert(asset3_txn.assetName === Bytes('AST3'), 'asset3_txn is correct') + + appCreateParams.set({ + note: '3rd', + }) + assetParams.set({ + note: '3rd', + }) + itxn.submitGroup(appCreateParams, assetParams) + } + + private test2() { + let createAppParams: itxn.ApplicationCallItxnParams + if (Txn.numAppArgs) { + const args = [Bytes('1'), Bytes('2')] as const + createAppParams = itxn.applicationCall({ + approvalProgram: APPROVE, + clearStateProgram: APPROVE, + appArgs: args, + onCompletion: arc4.OnCompleteAction.NoOp, + note: 'with args param set', + }) + } else { + createAppParams = itxn.applicationCall({ + approvalProgram: APPROVE, + clearStateProgram: APPROVE, + appArgs: [Bytes('3'), '4', Bytes('5')], + note: 'no args param set', + }) + } + const createAppTxn = createAppParams.submit() + assert(createAppTxn.appArgs(0) === Bytes('1'), 'correct args used 1') + assert(createAppTxn.appArgs(1) === Bytes('2'), 'correct args used 2') + assert(createAppTxn.note === Bytes('with args param set')) + } +} diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index f00504b..863d377 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -18,6 +18,7 @@ import { AccountCls } from '../src/impl/account' import { asBigInt, asNumber, asUint64Cls } from '../src/util' import { AppExpectingEffects } from './artifacts/created-app-asset/contract.algo' import { + ItxnDemoContract, ITxnOpsContract, StateAcctParamsGetContract, StateAppParamsContract, @@ -352,8 +353,18 @@ describe('State op codes', async () => { expect(asNumber((ctx.txn.lastActive as ApplicationTransaction).numLogs)).toEqual(0) expect((ctx.txn.lastActive as ApplicationTransaction).lastLog).toEqual(Bytes('')) - // Test created_app and created_asset (should be created for these transactions) + // Test created_app (should be created for these transactions) expect(appItxn.createdApp).toBeTruthy() }) + + it('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(() => { + contract.approvalProgram() + }) + ctx.txn.createScope([ctx.any.txn.applicationCall({ appArgs: [Bytes('test2')] })]).execute(() => { + contract.approvalProgram() + }) + }) }) }) From 6a75d1377274c4eb8c6af99d94fc12e9189684ef Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 1 Oct 2024 19:26:17 +0800 Subject: [PATCH 07/85] implement Scratch and add test for it --- src/impl/index.ts | 1 + src/impl/inner-transactions.ts | 16 +++++++-------- src/impl/scratch.ts | 25 ++++++++++++++++++++++++ src/impl/transactions.ts | 27 +++++++++++++++++++++++++- src/subcontexts/transaction-context.ts | 6 +++++- tests/state-op-codes.spec.ts | 19 ++++++++++++++++++ 6 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 src/impl/scratch.ts diff --git a/src/impl/index.ts b/src/impl/index.ts index 5c5c373..35d1294 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -8,3 +8,4 @@ export { GTxn } from './gtxn' export * from './pure' export { Txn, gaid } from './txn' export { GITxn, ITxn, ITxnCreate } from './itxn' +export { Scratch } from './scratch' diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts index 893b088..be86470 100644 --- a/src/impl/inner-transactions.ts +++ b/src/impl/inner-transactions.ts @@ -158,20 +158,20 @@ export class ApplicationInnerTxn extends ApplicationTransaction implements itxn. } } -export const createInnerTxn = (fields: TFields): T => { +export const createInnerTxn = (fields: TFields) => { switch (fields.type) { case TransactionType.Payment: - return new PaymentInnerTxn(fields) as T + return new PaymentInnerTxn(fields) case TransactionType.AssetConfig: - return new AssetConfigInnerTxn(fields) as T + return new AssetConfigInnerTxn(fields) case TransactionType.AssetTransfer: - return new AssetTransferInnerTxn(fields as itxn.AssetTransferFields) as T + return new AssetTransferInnerTxn(fields as itxn.AssetTransferFields) case TransactionType.AssetFreeze: - return new AssetFreezeInnerTxn(fields as itxn.AssetFreezeFields) as T + return new AssetFreezeInnerTxn(fields as itxn.AssetFreezeFields) case TransactionType.ApplicationCall: - return new ApplicationInnerTxn(fields) as unknown as T + return new ApplicationInnerTxn(fields) case TransactionType.KeyRegistration: - return new KeyRegistrationInnerTxn(fields) as T + return new KeyRegistrationInnerTxn(fields) default: throw new internal.errors.InternalError(`Invalid inner transaction type: ${fields.type}`) } @@ -211,7 +211,7 @@ export class ItxnParams(this.#fields) + return createInnerTxn(this.#fields) as unknown as TTransaction } set(p: Partial) { diff --git a/src/impl/scratch.ts b/src/impl/scratch.ts new file mode 100644 index 0000000..7efebd1 --- /dev/null +++ b/src/impl/scratch.ts @@ -0,0 +1,25 @@ +import { bytes, internal, uint64 } from '@algorandfoundation/algo-ts' +import { lazyContext } from '../context-helpers/internal-context' + +export const Scratch: internal.opTypes.ScratchType = { + loadBytes: function (a: internal.primitives.StubUint64Compat): bytes { + const result = lazyContext.activeGroup.activeTransaction.getScratchSlot(a) + if (result instanceof internal.primitives.BytesCls) { + return result as bytes + } + throw new internal.errors.InternalError('Invalid scratch slot type') + }, + loadUint64: function (a: internal.primitives.StubUint64Compat): uint64 { + const result = lazyContext.activeGroup.activeTransaction.getScratchSlot(a) + if (result instanceof internal.primitives.Uint64Cls) { + return result as uint64 + } + throw new internal.errors.InternalError('Invalid scratch slot type') + }, + store: function ( + a: internal.primitives.StubUint64Compat, + b: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, + ): void { + lazyContext.activeGroup.activeTransaction.setScratchSlot(a, b) + }, +} diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index de4fe08..04dbcaa 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -14,7 +14,7 @@ import { import { MAX_ITEMS_IN_LOG } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { Mutable, ObjectKeys } from '../typescript-helpers' -import { asBytes, asNumber, asUint64Cls, combineIntoMaxBytePages, getRandomBytes } from '../util' +import { asBytes, asMaybeBytesCls, asMaybeUint64Cls, asNumber, asUint64Cls, combineIntoMaxBytePages, getRandomBytes } from '../util' const baseDefaultFields = () => ({ sender: lazyContext.defaultSender, @@ -44,6 +44,7 @@ abstract class TransactionBase { this.groupIndex = fields.groupIndex ?? baseDefaults.groupIndex this.txnId = fields.txnId ?? baseDefaults.txnId this.rekeyTo = fields.rekeyTo ?? baseDefaults.rekeyTo + this.scratchSpace = Array(256).fill(Uint64(0)) } readonly sender: Account @@ -56,6 +57,28 @@ abstract class TransactionBase { readonly groupIndex: uint64 readonly txnId: bytes readonly rekeyTo: Account + readonly scratchSpace: Array + + setScratchSlot( + index: internal.primitives.StubUint64Compat, + value: internal.primitives.StubBytesCompat | internal.primitives.StubUint64Compat, + ): void { + const i = asNumber(index) + if (i >= this.scratchSpace.length) { + throw internal.errors.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 { + const i = asNumber(index) + if (i >= this.scratchSpace.length) { + throw internal.errors.internalError('invalid scratch slot') + } + return this.scratchSpace[i] + } } export class PaymentTransaction extends TransactionBase implements gtxn.PaymentTxn { @@ -201,6 +224,7 @@ export type ApplicationTransactionFields = TxnFields & approvalProgramPages: Array clearStateProgramPages: Array appLogs: Array + scratchSpace: Array }> export class ApplicationTransaction extends TransactionBase implements gtxn.ApplicationTxn { @@ -233,6 +257,7 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl this.#apps = fields.apps ?? [] this.#approvalProgramPages = fields.approvalProgramPages ?? (fields.approvalProgram ? [fields.approvalProgram] : []) this.#clearStateProgramPages = fields.clearStateProgramPages ?? (fields.clearStateProgram ? [fields.clearStateProgram] : []) + fields.scratchSpace?.forEach((v, i) => this.setScratchSlot(i, v)) } readonly appId: Application diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 529eee4..64e9b0a 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -1,4 +1,4 @@ -import { internal, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import { bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algo-ts' import algosdk from 'algosdk' import { lazyContext } from '../context-helpers/internal-context' import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' @@ -162,6 +162,10 @@ export class TransactionGroup { return this.constructingItxnGroup.at(-1)! } + getScratchSlot(index: internal.primitives.StubUint64Compat): bytes | uint64 { + return this.activeTransaction.getScratchSlot(index) + } + patchActiveTransactionFields(fields: AllTransactionFields) { const activeTransaction = this.activeTransaction as unknown as AllTransactionFields const filteredFields = Object.fromEntries(Object.entries(fields).filter(([_, value]) => value !== undefined)) diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 863d377..8f86d1f 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -367,4 +367,23 @@ describe('State op codes', async () => { }) }) }) + + describe('Scratch', async () => { + test.each([ + [0, Bytes('test_bytes')], + [1, Uint64(42)], + [2, Bytes('test_bytes')], + [3, Uint64(42)], + [255, Bytes('max_index')], + ])('should return the correct field value of the scratch slot', async (index: number, value: bytes | uint64) => { + const newScratchSpace = Array(256).fill(Uint64(0)) + newScratchSpace[index] = value + + ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: newScratchSpace })]).execute(() => {}) + + expect(ctx.txn.lastGroup.getScratchSlot(index)).toEqual(value) + + expect(() => ctx.txn.lastGroup.getScratchSlot(256)).toThrow('invalid scratch slot') + }) + }) }) From 773a39f14713ac92a021509596e36887a0ee414a Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Wed, 2 Oct 2024 15:23:51 -0700 Subject: [PATCH 08/85] build: Add build pipelines and prepare package for publishing --- .github/workflows/node-ci.yml | 179 + .github/workflows/pr.yml | 27 + .github/workflows/release.yml | 66 + .idea/.gitignore | 5 + .idea/algorand-typescript-testing.iml | 12 + .idea/codeStyles/Project.xml | 62 + .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/jsLinters/eslint.xml | 6 + .idea/modules.xml | 8 + .idea/prettier.xml | 6 + .idea/vcs.xml | 6 + .releaserc.json | 64 + .tstoolkitrc.ts | 12 +- commitlint.config.cjs | 15 + examples/auction/contract.algo.ts | 4 +- examples/calculator/contract.algo.ts | 4 +- examples/calculator/contract.spec.ts | 5 +- examples/hello-world-abi/contract.algo.ts | 2 +- examples/hello-world-abi/contract.spec.ts | 4 +- examples/hello-world/contract.algo.ts | 2 +- examples/hello-world/contract.spec.ts | 4 +- examples/rollup.config.ts | 36 + examples/simple-voting/contract.algo.ts | 4 +- examples/simple-voting/contract.spec.ts | 6 +- examples/tealscript/example.algo.ts | 4 +- examples/tealscript/teal-script-base.algo.ts | 2 +- examples/voting/contract.algo.ts | 4 +- package-lock.json | 7261 +++++++++++++++-- package.json | 32 +- src/abi-metadata.ts | 4 +- src/constants.ts | 2 +- src/context-helpers/internal-context.ts | 2 +- src/decode-logs.ts | 2 +- src/errors.ts | 2 +- src/impl/account.ts | 2 +- src/impl/acct-params.ts | 2 +- src/impl/app-params.ts | 2 +- src/impl/application.ts | 2 +- src/impl/asset-holding.ts | 2 +- src/impl/asset-params.ts | 2 +- src/impl/asset.ts | 2 +- src/impl/crypto.ts | 2 +- src/impl/global.ts | 2 +- src/impl/gtxn.ts | 2 +- src/impl/inner-transactions.ts | 2 +- src/impl/itxn.ts | 2 +- src/impl/pure.ts | 2 +- src/impl/scratch.ts | 2 +- src/impl/transactions.ts | 2 +- src/impl/txn.ts | 2 +- src/runtime-helpers.ts | 3 +- src/subcontexts/contract-context.ts | 2 +- src/subcontexts/ledger-context.ts | 2 +- src/subcontexts/transaction-context.ts | 2 +- src/test-execution-context.ts | 2 +- src/test-transformer/index.ts | 48 +- src/test-transformer/node-factory.ts | 7 +- src/test-transformer/visitors.ts | 6 +- src/util.ts | 2 +- src/value-generators/avm.ts | 2 +- src/value-generators/txn.ts | 2 +- .../created-app-asset/contract.algo.ts | 2 +- tests/artifacts/state-ops/contract.algo.ts | 2 +- tests/avm-invoker.ts | 2 +- tests/crypto-op-codes.spec.ts | 2 +- tests/primitives/biguint.spec.ts | 4 +- tests/primitives/bytes.spec.ts | 2 +- tests/primitives/uint64.spec.ts | 2 +- tests/pure-op-codes.spec.ts | 2 +- tests/references/asset.spec.ts | 2 +- tests/state-op-codes.spec.ts | 2 +- tests/util.ts | 2 +- tsconfig.json | 11 +- vitest.config.mts | 7 +- 75 files changed, 7304 insertions(+), 713 deletions(-) create mode 100644 .github/workflows/node-ci.yml create mode 100644 .github/workflows/pr.yml create mode 100644 .github/workflows/release.yml create mode 100644 .idea/.gitignore create mode 100644 .idea/algorand-typescript-testing.iml create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/jsLinters/eslint.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/prettier.xml create mode 100644 .idea/vcs.xml create mode 100644 .releaserc.json create mode 100644 commitlint.config.cjs create mode 100644 examples/rollup.config.ts diff --git a/.github/workflows/node-ci.yml b/.github/workflows/node-ci.yml new file mode 100644 index 0000000..22ddccf --- /dev/null +++ b/.github/workflows/node-ci.yml @@ -0,0 +1,179 @@ +on: + workflow_call: + inputs: + node-version: + required: false + type: string + default: 18.x + working-directory: + required: false + type: string + default: '.' + lint-script: + required: false + type: string + default: npm run lint --if-present + compile-script: + required: false + type: string + default: npm run check-types --if-present + pre-test-script: + required: false + type: string + test-script: + required: false + type: string + default: npm run test --if-present + test-environment-variables: + required: false + type: string + default: '{}' + output-test-results: + required: false + type: boolean + default: false + test-results-file-pattern: + required: false + type: string + default: '**/test-results.xml' + audit-script: + required: false + type: string + default: npm audit + build-script: + required: false + type: string + default: npm run build + run-build: + required: false + type: boolean + default: false + run-commit-lint: + required: false + type: boolean + default: false + commit-lint-script: + required: false + type: string + default: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose + pre-run-script: + required: false + type: string + upload-artifact-name: + required: false + type: string + upload-artifact-path: + required: false + description: The full path to the artifact directory, this path does not take working-directory into account + type: string + default: . + + download-artifact-name: + required: false + type: string + download-artifact-pattern: + required: false + type: string + download-artifact-path: + required: false + description: The full path to the artifact directory, this path does not take working-directory into account + type: string + default: . + + secrets: + npm-auth-token: + description: NPM auth token (don't pass in on a PR build on a public repository) + required: false + +jobs: + node-ci: + runs-on: ubuntu-latest + + defaults: + run: + shell: bash + working-directory: ${{ inputs.working-directory }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # setup node + private repo access + - name: Use Node.js ${{ inputs.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node-version }} + registry-url: 'https://npm.pkg.github.com' + scope: '@makerxstudio' + cache: 'npm' + cache-dependency-path: ${{ inputs.working-directory }}/package-lock.json + + - name: Download artifacts + if: ${{ inputs.download-artifact-name || inputs.download-artifact-pattern }} + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.download-artifact-name }} + pattern: ${{ inputs.download-artifact-pattern }} + path: ${{ inputs.download-artifact-path }} + + - name: Pre-run + if: ${{ inputs.pre-run-script }} + run: ${{ inputs.pre-run-script }} + + # run npm ci preventing script access to npm auth token + - run: npm ci --ignore-scripts + env: + NODE_AUTH_TOKEN: ${{ secrets.npm-auth-token || secrets.GITHUB_TOKEN }} + # allow scripts to run without npm auth token + - run: npm rebuild && npm run prepare --if-present + + # run all the CI scripts + - name: 'Commit lint' + if: ${{ inputs.run-commit-lint }} + run: ${{ inputs.commit-lint-script }} + + - name: Lint + run: ${{ inputs.lint-script }} + + - name: Compile + run: ${{ inputs.compile-script }} + + - name: Pre-test + if: ${{ inputs.pre-test-script }} + run: ${{ inputs.pre-test-script }} + + - name: Test + run: ${{ inputs.test-script }} + env: ${{ fromJson(inputs.test-environment-variables) }} + + #Requires permissions.checks: write + - name: Publish test results + if: ${{ inputs.output-test-results }} + uses: phoenix-actions/test-reporting@v10 + with: + name: Test results + path: ${{ inputs.test-results-file-pattern }} + reporter: jest-junit + output-to: checks + fail-on-error: false + + - name: Audit + run: ${{ inputs.audit-script }} + + - name: Build + if: ${{ inputs.run-build }} + run: ${{ inputs.build-script }} + # CDK infrastructure build calls npm ci on /infrastructure/build, which may fail without NODE_AUTH_TOKEN + env: + NODE_AUTH_TOKEN: ${{ secrets.npm-auth-token || secrets.GITHUB_TOKEN }} + + - name: Publish artifact + if: ${{ inputs.upload-artifact-name }} + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.upload-artifact-name }} + path: ${{ inputs.upload-artifact-path }} + + diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..c2e6eb1 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,27 @@ +name: Pull Request + +on: + pull_request: + branches: + - main + - alpha + paths-ignore: + - 'docs/**' + - 'scripts/**' + + +permissions: + contents: read + +jobs: + build: + name: 'Build @algorandfoundation/algorand-typescript-testing' + uses: ./.github/workflows/node-ci.yml + with: + pre-test-script: | + pipx install algokit + algokit localnet start + node-version: 20.x + run-build: true + run-commit-lint: true + audit-script: npm run audit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..1af00be --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,66 @@ +name: Publish + +on: + push: + branches: + - alpha + - main + - release + workflow_dispatch: + +concurrency: release + +permissions: + contents: write + issues: write + pull-requests: write + +jobs: + build: + name: 'Build @algorandfoundation/algorand-typescript-testing' + uses: ./.github/workflows/node-ci.yml + with: + pre-test-script: | + pipx install algokit + algokit localnet start + node-version: 20.x + run-build: true + run-commit-lint: true + audit-script: npm run audit + upload-artifact-name: algo-ts-testing + upload-artifact-path: ./dist + + release: + name: Release + needs: build + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Use Node.js 20.x + uses: actions/setup-node@v4 + with: + node-version: 20.x + + - run: npm ci --ignore-scripts + + - name: Download package artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Generate semantic version for @algorandfoundation/algorand-typescript-testing + run: npx semantic-release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Publish @algorandfoundation/algorand-typescript-testing + uses: JS-DevTools/npm-publish@v3 + id: publish-puya-ts + with: + token: ${{ secrets.NPM_TOKEN }} + package: artifacts/algo-ts-testing/package.json + access: 'public' diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/algorand-typescript-testing.iml b/.idea/algorand-typescript-testing.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/algorand-typescript-testing.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..2457aec --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/jsLinters/eslint.xml b/.idea/jsLinters/eslint.xml new file mode 100644 index 0000000..541945b --- /dev/null +++ b/.idea/jsLinters/eslint.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0d323e9 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/prettier.xml b/.idea/prettier.xml new file mode 100644 index 0000000..b0c1c68 --- /dev/null +++ b/.idea/prettier.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..63b2fc5 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,64 @@ +{ + "branches": [ + { + "name": "main", + "prerelease": "beta" + }, + { + "name": "release" + }, + { + "name": "alpha", + "prerelease": "alpha" + } + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "type": "build", + "release": "patch" + }, + { + "type": "chore", + "release": "patch" + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "build", + "section": "Dependencies and Other Build Updates", + "hidden": false + } + ] + } + } + ], + [ + "@semantic-release/npm", + { + "npmPublish": false, + "pkgRoot": "artifacts/algo-ts-testing" + } + ], + "@semantic-release/github" + ] +} diff --git a/.tstoolkitrc.ts b/.tstoolkitrc.ts index 1b3e509..27cbfce 100644 --- a/.tstoolkitrc.ts +++ b/.tstoolkitrc.ts @@ -1,15 +1,17 @@ -import type { TsToolkitConfig } from "@makerx/ts-toolkit"; +import type { TsToolkitConfig } from '@makerx/ts-toolkit' const config: TsToolkitConfig = { packageConfig: { srcDir: 'src', outDir: 'dist', moduleType: 'module', + exportTypes: 'module', main: 'index.ts', exports: { - '.': "index.ts", - './runtime-helpers': 'runtime-helpers.ts' - } - } + '.': 'index.ts', + './runtime-helpers': 'runtime-helpers.ts', + './test-transformer': 'test-transformer.ts', + }, + }, } export default config diff --git a/commitlint.config.cjs b/commitlint.config.cjs new file mode 100644 index 0000000..9472837 --- /dev/null +++ b/commitlint.config.cjs @@ -0,0 +1,15 @@ +module.exports = { + extends: ['@commitlint/config-conventional'], + rules: { + // Allow sentence case commit messages + 'subject-case': [1, 'always', ['pascal-case', 'upper-case']], + 'type-empty': [1, 'never'], + 'subject-empty': [1, 'always'], + 'body-leading-blank': [0, 'always'], + 'body-max-line-length': [1, 'always', 200], + 'header-max-length': [1, 'always', 150], + 'footer-max-length': [1, 'always', 150], + 'footer-max-line-length': [1, 'always', 150], + }, +} + diff --git a/examples/auction/contract.algo.ts b/examples/auction/contract.algo.ts index 810cba0..725d747 100644 --- a/examples/auction/contract.algo.ts +++ b/examples/auction/contract.algo.ts @@ -1,4 +1,4 @@ -import type { gtxn, uint64 } from '@algorandfoundation/algo-ts' +import type { gtxn, uint64 } from '@algorandfoundation/algorand-typescript' import { abimethod, Account, @@ -11,7 +11,7 @@ import { itxn, LocalState, Txn, -} from '@algorandfoundation/algo-ts' +} from '@algorandfoundation/algorand-typescript' export class Auction extends Contract { previousBidder = GlobalState() diff --git a/examples/calculator/contract.algo.ts b/examples/calculator/contract.algo.ts index f21a5f8..3180789 100644 --- a/examples/calculator/contract.algo.ts +++ b/examples/calculator/contract.algo.ts @@ -1,5 +1,5 @@ -import type { uint64 } from '@algorandfoundation/algo-ts' -import { assert, Bytes, Contract, err, log, op, Txn, Uint64 } from '@algorandfoundation/algo-ts' +import type { uint64 } from '@algorandfoundation/algorand-typescript' +import { assert, Bytes, Contract, 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 5bf6a56..a57ccd1 100644 --- a/examples/calculator/contract.spec.ts +++ b/examples/calculator/contract.spec.ts @@ -1,7 +1,6 @@ -import { internal, op, Uint64 } from '@algorandfoundation/algo-ts' +import { internal, op, Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, it } from 'vitest' - -import { TestExecutionContext } from '@algorandfoundation/algo-ts-testing' import MyContract from './contract.algo' describe('Calculator', () => { diff --git a/examples/hello-world-abi/contract.algo.ts b/examples/hello-world-abi/contract.algo.ts index 1636f50..f27adf0 100644 --- a/examples/hello-world-abi/contract.algo.ts +++ b/examples/hello-world-abi/contract.algo.ts @@ -1,4 +1,4 @@ -import { arc4, log } from '@algorandfoundation/algo-ts' +import { arc4, log } from '@algorandfoundation/algorand-typescript' abstract class Intermediate extends arc4.Contract { @arc4.abimethod({ allowActions: ['NoOp'], readonly: true }) diff --git a/examples/hello-world-abi/contract.spec.ts b/examples/hello-world-abi/contract.spec.ts index 1cd18fb..32ad91b 100644 --- a/examples/hello-world-abi/contract.spec.ts +++ b/examples/hello-world-abi/contract.spec.ts @@ -1,5 +1,5 @@ -import { assert, TransactionType } from '@algorandfoundation/algo-ts' -import { TestExecutionContext } from '@algorandfoundation/algo-ts-testing' +import { assert, TransactionType } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, it } from 'vitest' import HelloWorldContract from './contract.algo' diff --git a/examples/hello-world/contract.algo.ts b/examples/hello-world/contract.algo.ts index 6ac05f7..00023d6 100644 --- a/examples/hello-world/contract.algo.ts +++ b/examples/hello-world/contract.algo.ts @@ -1,4 +1,4 @@ -import { BaseContract, log, op } from '@algorandfoundation/algo-ts' +import { BaseContract, log, op } from '@algorandfoundation/algorand-typescript' export default class HelloWorldContract extends BaseContract { public approvalProgram(): boolean { diff --git a/examples/hello-world/contract.spec.ts b/examples/hello-world/contract.spec.ts index 1e6b20d..a06e2d0 100644 --- a/examples/hello-world/contract.spec.ts +++ b/examples/hello-world/contract.spec.ts @@ -1,5 +1,5 @@ -import { Bytes } from '@algorandfoundation/algo-ts' -import { TestExecutionContext } from '@algorandfoundation/algo-ts-testing' +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, it } from 'vitest' import HelloWorldContract from './contract.algo' diff --git a/examples/rollup.config.ts b/examples/rollup.config.ts new file mode 100644 index 0000000..455a291 --- /dev/null +++ b/examples/rollup.config.ts @@ -0,0 +1,36 @@ +import typescript from '@rollup/plugin-typescript' +import type { RollupOptions } from 'rollup' +import { puyaTsTransformer } from '../src/test-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/hello-world-abi/contract.algo.ts', + 'examples/hello-world/contract.algo.ts', + 'examples/auction/contract.algo.ts', + 'examples/voting/contract.algo.ts', + 'examples/simple-voting/contract.algo.ts', + ], + output: [ + { + dir: 'examples/debug-out', + format: 'es', + exports: 'named', + entryFileNames: '[name].mjs', + preserveModules: true, + sourcemap: true, + }, + ], + external: [/node_modules/, /tslib/, /@algorandfoundation\/algorand-typescript/], + plugins: [ + typescript({ + tsconfig: './tsconfig.json', + transformers: { + before: [puyaTsTransformer({})], + }, + }), + ], +} + +export default config diff --git a/examples/simple-voting/contract.algo.ts b/examples/simple-voting/contract.algo.ts index 6d8b2f5..d8159b3 100644 --- a/examples/simple-voting/contract.algo.ts +++ b/examples/simple-voting/contract.algo.ts @@ -1,5 +1,5 @@ -import type { Account, bytes, uint64 } from '@algorandfoundation/algo-ts' -import { assert, BaseContract, Bytes, GlobalState, LocalState, op, TransactionType, Uint64 } from '@algorandfoundation/algo-ts' +import type { Account, bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { assert, BaseContract, Bytes, GlobalState, LocalState, op, TransactionType, Uint64 } from '@algorandfoundation/algorand-typescript' const VOTE_PRICE = Uint64(10_000) export default class SimpleVotingContract extends BaseContract { diff --git a/examples/simple-voting/contract.spec.ts b/examples/simple-voting/contract.spec.ts index 9d5ed07..9d28685 100644 --- a/examples/simple-voting/contract.spec.ts +++ b/examples/simple-voting/contract.spec.ts @@ -1,6 +1,6 @@ -import type { Account, uint64 } from '@algorandfoundation/algo-ts' -import { Bytes, Uint64 } from '@algorandfoundation/algo-ts' -import { TestExecutionContext } from '@algorandfoundation/algo-ts-testing' +import type { Account, uint64 } from '@algorandfoundation/algorand-typescript' +import { Bytes, Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, it } from 'vitest' import SimpleVotingContract from './contract.algo' diff --git a/examples/tealscript/example.algo.ts b/examples/tealscript/example.algo.ts index b013331..a373d73 100644 --- a/examples/tealscript/example.algo.ts +++ b/examples/tealscript/example.algo.ts @@ -1,5 +1,5 @@ -import type { bytes } from '@algorandfoundation/algo-ts' -import { abimethod, Bytes, log, Uint64 } from '@algorandfoundation/algo-ts' +import type { bytes } from '@algorandfoundation/algorand-typescript' +import { abimethod, Bytes, log, Uint64 } from '@algorandfoundation/algorand-typescript' import { TealScriptBase } from './teal-script-base.algo' export default class ExampleTealScript extends TealScriptBase { diff --git a/examples/tealscript/teal-script-base.algo.ts b/examples/tealscript/teal-script-base.algo.ts index 1cbb963..f78a8e2 100644 --- a/examples/tealscript/teal-script-base.algo.ts +++ b/examples/tealscript/teal-script-base.algo.ts @@ -1,4 +1,4 @@ -import { arc4, Contract, err } from '@algorandfoundation/algo-ts' +import { arc4, Contract, err } from '@algorandfoundation/algorand-typescript' export abstract class TealScriptBase extends Contract { @arc4.abimethod({ allowActions: 'DeleteApplication' }) diff --git a/examples/voting/contract.algo.ts b/examples/voting/contract.algo.ts index 42e2949..53a43e3 100644 --- a/examples/voting/contract.algo.ts +++ b/examples/voting/contract.algo.ts @@ -1,4 +1,4 @@ -import type { Account, Asset, bytes, gtxn, uint64 } from '@algorandfoundation/algo-ts' +import type { Account, Asset, bytes, gtxn, uint64 } from '@algorandfoundation/algorand-typescript' import { abimethod, arc4, @@ -17,7 +17,7 @@ import { Txn, Uint64, urange, -} from '@algorandfoundation/algo-ts' +} from '@algorandfoundation/algorand-typescript' type VoteIndexArray = arc4.DynamicArray> diff --git a/package-lock.json b/package-lock.json index 81a6ee7..5fcf5f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,16 @@ { - "name": "@algorandfoundation/algo-ts-testing", + "name": "@algorandfoundation/algorand-typescript-testing", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@algorandfoundation/algo-ts-testing", + "name": "@algorandfoundation/algorand-typescript-testing", "version": "1.0.0", "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.2", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.5", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", @@ -17,14 +19,13 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@algorandfoundation/algo-ts": "file:../puya-ts/packages/algo-ts/dist", - "@algorandfoundation/algo-ts-testing": "file:./dist", - "@algorandfoundation/puya-ts": "file:../puya-ts/dist", + "@commitlint/cli": "^19.5.0", + "@commitlint/config-conventional": "^19.5.0", "@eslint/eslintrc": "3.1.0", "@eslint/js": "9.11.1", "@makerx/eslint-config": "4.0.0", "@makerx/prettier-config": "2.0.1", - "@makerx/ts-toolkit": "4.0.0-beta.20", + "@makerx/ts-toolkit": "4.0.0-beta.21", "@rollup/plugin-commonjs": "28.0.0", "@rollup/plugin-json": "6.1.0", "@rollup/plugin-node-resolve": "15.3.0", @@ -36,6 +37,7 @@ "@typescript-eslint/parser": "8.7.0", "@vitest/coverage-v8": "2.1.1", "better-npm-audit": "3.11.0", + "conventional-changelog-conventionalcommits": "^8.0.0", "copyfiles": "2.4.1", "eslint": "9.11.1", "eslint-config-prettier": "^9.1.0", @@ -44,58 +46,35 @@ "prettier": "3.3.3", "rimraf": "6.0.1", "rollup": "^4.22.4", + "semantic-release": "^24.1.1", "tsx": "4.19.1", "typescript": "^5.6.2", "vitest": "2.1.1" }, "peerDependencies": { - "@algorandfoundation/algo-ts": "*", - "@algorandfoundation/puya-ts": "*", "tslib": "^2.6.2" } }, "../algo-ts/dist": { - "name": "@algorandfoundation/algo-ts", + "name": "@algorandfoundation/algorand-typescript", "version": "1.0.0", "extraneous": true, "peerDependencies": { "tslib": "^2.6.2" } }, - "../puya-ts/dist": { - "name": "@algorandfoundation/puya-ts", - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0", - "change-case": "^5.4.4", - "commander": "^12.1.0", - "cross-spawn": "^7.0.3", - "glob": "^11.0.0", - "polytype": "^0.17.0", - "zod": "^3.23.8" - }, - "bin": { - "puya-ts": "bin/run-cli.mjs", - "puyats": "bin/run-cli.mjs" - }, - "peerDependencies": { - "@algorandfoundation/algorand-typescript": "0.0.1-alpha.1" - } - }, "../puya-ts/packages/algo-ts/dist": { "name": "@algorandfoundation/algorand-typescript", "version": "0.0.1-alpha.1", - "dev": true, + "extraneous": true, "peerDependencies": { "tslib": "^2.6.2" } }, "dist": { - "name": "@algorandfoundation/algo-ts-testing", + "name": "@algorandfoundation/algorand-typescript-testing", "version": "1.0.0", - "dev": true, + "extraneous": true, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", "algosdk": "^2.9.0", @@ -106,19 +85,9 @@ "tweetnacl": "^1.0.3" }, "peerDependencies": { - "@algorandfoundation/algo-ts": "*", - "@algorandfoundation/puya-ts": "*", "tslib": "^2.6.2" } }, - "node_modules/@algorandfoundation/algo-ts": { - "resolved": "../puya-ts/packages/algo-ts/dist", - "link": true - }, - "node_modules/@algorandfoundation/algo-ts-testing": { - "resolved": "dist", - "link": true - }, "node_modules/@algorandfoundation/algokit-utils": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-utils/-/algokit-utils-6.2.1.tgz", @@ -133,9 +102,61 @@ "algosdk": "^2.7.0" } }, + "node_modules/@algorandfoundation/algorand-typescript": { + "version": "0.0.1-alpha.2", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.2.tgz", + "integrity": "sha512-ULqsgvaLp8L3P0dgukjQSfYRvGkc7S/wVeOxO+w5+GVJ7+kqQbAtCgRhqdYXjc4Mle6VKsSc87GW/zgXGVZlHg==", + "peerDependencies": { + "tslib": "^2.6.2" + } + }, "node_modules/@algorandfoundation/puya-ts": { - "resolved": "../puya-ts/dist", - "link": true + "version": "1.0.0-alpha.5", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.5.tgz", + "integrity": "sha512-OFzquX8EpzeRWH2+2FDnfymCe5lBpP+ZrvqPtXNy2cYaq7YE8hzT+pU2bujvDH3IeP8G0vVv8rDISyCXR4R96A==", + "bundleDependencies": [ + "typescript" + ], + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "change-case": "^5.4.4", + "commander": "^12.1.0", + "cross-spawn": "^7.0.3", + "glob": "^11.0.0", + "polytype": "^0.17.0", + "typescript": "^5.6.2", + "upath": "^2.0.1", + "zod": "^3.23.8" + }, + "bin": { + "puya-ts": "bin/run-cli.mjs", + "puyats": "bin/run-cli.mjs" + } + }, + "node_modules/@algorandfoundation/puya-ts/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@algorandfoundation/puya-ts/node_modules/typescript": { + "version": "5.6.2", + "inBundle": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } }, "node_modules/@ampproject/remapping": { "version": "2.3.0", @@ -299,299 +320,582 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "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==", - "cpu": [ - "ppc64" - ], + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "aix" - ], "engines": { - "node": ">=18" + "node": ">=0.1.90" } }, - "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==", - "cpu": [ - "arm" - ], + "node_modules/@commitlint/cli": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.5.0.tgz", + "integrity": "sha512-gaGqSliGwB86MDmAAKAtV9SV1SHdmN8pnGq4EJU4+hLisQ7IFfx4jvU4s+pk6tl0+9bv6yT+CaZkufOinkSJIQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@commitlint/format": "^19.5.0", + "@commitlint/lint": "^19.5.0", + "@commitlint/load": "^19.5.0", + "@commitlint/read": "^19.5.0", + "@commitlint/types": "^19.5.0", + "tinyexec": "^0.3.0", + "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, "engines": { - "node": ">=18" + "node": ">=v18" } }, - "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==", - "cpu": [ - "arm64" - ], + "node_modules/@commitlint/cli/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, "engines": { - "node": ">=18" + "node": ">=12" } }, - "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==", - "cpu": [ - "x64" - ], + "node_modules/@commitlint/cli/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, "engines": { - "node": ">=18" + "node": ">=12" } }, - "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==", - "cpu": [ - "arm64" - ], + "node_modules/@commitlint/cli/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "license": "ISC", "engines": { - "node": ">=18" + "node": ">=12" } }, - "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==", - "cpu": [ - "x64" - ], + "node_modules/@commitlint/config-conventional": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.5.0.tgz", + "integrity": "sha512-OBhdtJyHNPryZKg0fFpZNOBM1ZDbntMvqMuSmpfyP86XSfwzGw4CaoYRG4RutUPg0BTK07VMRIkNJT6wi2zthg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@commitlint/types": "^19.5.0", + "conventional-changelog-conventionalcommits": "^7.0.2" + }, "engines": { - "node": ">=18" + "node": ">=v18" } }, - "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==", - "cpu": [ - "arm64" - ], + "node_modules/@commitlint/config-conventional/node_modules/conventional-changelog-conventionalcommits": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz", + "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, "engines": { - "node": ">=18" + "node": ">=16" } }, - "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==", - "cpu": [ - "x64" - ], + "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==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@commitlint/types": "^19.5.0", + "ajv": "^8.11.0" + }, "engines": { - "node": ">=18" + "node": ">=v18" } }, - "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==", - "cpu": [ - "arm" - ], + "node_modules/@commitlint/config-validator/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "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==", - "cpu": [ - "arm64" - ], + "node_modules/@commitlint/config-validator/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "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==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@commitlint/types": "^19.5.0", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, "engines": { - "node": ">=18" + "node": ">=v18" } }, - "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==", - "cpu": [ - "ia32" - ], + "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==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=18" + "node": ">=v18" } }, - "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==", - "cpu": [ - "loong64" - ], + "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==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@commitlint/types": "^19.5.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/format/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@commitlint/is-ignored": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.5.0.tgz", + "integrity": "sha512-0XQ7Llsf9iL/ANtwyZ6G0NGp5Y3EQ8eDQSxv/SRcfJ0awlBY4tHFAvwWbw66FVUaWICH7iE5en+FD9TQsokZ5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.5.0", + "semver": "^7.6.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/lint": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.5.0.tgz", + "integrity": "sha512-cAAQwJcRtiBxQWO0eprrAbOurtJz8U6MgYqLz+p9kLElirzSCc0vGMcyCaA1O7AqBuxo11l1XsY3FhOFowLAAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/is-ignored": "^19.5.0", + "@commitlint/parse": "^19.5.0", + "@commitlint/rules": "^19.5.0", + "@commitlint/types": "^19.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.5.0.tgz", + "integrity": "sha512-INOUhkL/qaKqwcTUvCE8iIUf5XHsEPCLY9looJ/ipzi7jtGhgmtH7OOFiNvwYgH7mA8osUWOUDV8t4E2HAi4xA==", + "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", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^5.0.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@commitlint/message": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.5.0.tgz", + "integrity": "sha512-R7AM4YnbxN1Joj1tMfCyBryOC5aNJBdxadTZkuqtWi3Xj0kMdutq16XQwuoGbIzL2Pk62TALV1fZDCv36+JhTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.5.0", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/top-level": "^19.5.0", + "@commitlint/types": "^19.5.0", + "git-raw-commits": "^4.0.0", + "minimist": "^1.2.8", + "tinyexec": "^0.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^19.5.0", + "@commitlint/types": "^19.5.0", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/resolve-extends/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@commitlint/rules": { + "version": "19.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.5.0.tgz", + "integrity": "sha512-hDW5TPyf/h1/EufSHEKSp6Hs+YVsDMHazfJ2azIk9tHPXS6UqSz1dIRs1gpqS3eMXgtkT7JH6TW4IShdqOwhAw==", + "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" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^7.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level/node_modules/find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@esbuild/linux-mips64el": { + "node_modules/@commitlint/top-level/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@commitlint/top-level/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/types/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@esbuild/aix-ppc64": { "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==", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", "cpu": [ - "mips64el" + "ppc64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "aix" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/linux-ppc64": { + "node_modules/@esbuild/android-arm": { "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", - "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", "cpu": [ - "ppc64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/linux-riscv64": { + "node_modules/@esbuild/android-arm64": { "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", - "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", "cpu": [ - "riscv64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/linux-s390x": { + "node_modules/@esbuild/android-x64": { "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==", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", "cpu": [ - "s390x" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/linux-x64": { + "node_modules/@esbuild/darwin-arm64": { "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", - "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "darwin" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/netbsd-x64": { + "node_modules/@esbuild/darwin-x64": { "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", - "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", "cpu": [ "x64" ], @@ -599,16 +903,16 @@ "license": "MIT", "optional": true, "os": [ - "netbsd" + "darwin" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/openbsd-arm64": { + "node_modules/@esbuild/freebsd-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==", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", "cpu": [ "arm64" ], @@ -616,16 +920,16 @@ "license": "MIT", "optional": true, "os": [ - "openbsd" + "freebsd" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/openbsd-x64": { + "node_modules/@esbuild/freebsd-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==", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", "cpu": [ "x64" ], @@ -633,30 +937,234 @@ "license": "MIT", "optional": true, "os": [ - "openbsd" + "freebsd" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/sunos-x64": { + "node_modules/@esbuild/linux-arm": { "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", - "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", "cpu": [ - "x64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "sunos" + "linux" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/win32-arm64": { + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "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==", @@ -893,7 +1401,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -911,7 +1418,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -924,7 +1430,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -937,14 +1442,12 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -962,7 +1465,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -978,7 +1480,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -1065,9 +1566,9 @@ "dev": true }, "node_modules/@makerx/ts-toolkit": { - "version": "4.0.0-beta.20", - "resolved": "https://registry.npmjs.org/@makerx/ts-toolkit/-/ts-toolkit-4.0.0-beta.20.tgz", - "integrity": "sha512-faZyycGxk7lKvhm0nwy5hirwD6tVAdLLbEYh9kd13OzHuWiHPySt3ixdB2BXHDzoE65BU43h8X/pqlUNDbH4NA==", + "version": "4.0.0-beta.21", + "resolved": "https://registry.npmjs.org/@makerx/ts-toolkit/-/ts-toolkit-4.0.0-beta.21.tgz", + "integrity": "sha512-/2zTLS2cxGonnRNTHx9Q5byd+M0HJak8UxUJSbmoXUKRFpAPfLhsrXvQKtavyExtMf2a49D4QSVuIbBy5VY9Gw==", "dev": true, "license": "MIT", "dependencies": { @@ -1119,64 +1620,264 @@ "node": ">= 8" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "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==", "dev": true, "license": "MIT", - "optional": true, "engines": { - "node": ">=14" + "node": ">= 18" } }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "node_modules/@octokit/core": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.2.tgz", + "integrity": "sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==", "dev": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + "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", + "before-after-hook": "^3.0.2", + "universal-user-agent": "^7.0.0" }, - "funding": { - "url": "https://opencollective.com/unts" + "engines": { + "node": ">= 18" } }, - "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==", + "node_modules/@octokit/endpoint": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz", + "integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==", "dev": true, "license": "MIT", "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "fdir": "^6.1.1", - "is-reference": "1.2.1", - "magic-string": "^0.30.3", - "picomatch": "^2.3.1" + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.2" }, "engines": { - "node": ">=16.0.0 || 14 >= 14.17" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } + "node": ">= 18" } }, - "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==", + "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==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8.6" + "dependencies": { + "@octokit/request": "^9.0.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.5.tgz", + "integrity": "sha512-cgwIRtKrpwhLoBi0CUNuY83DPGRMaWVjqVI/bGKsLJ4PzyWZNaEmhHroI2xlrVXkk6nFv0IsZpOp+ZWSWUS2AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request-error": "^6.0.0", + "@octokit/types": "^13.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-throttling": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.3.1.tgz", + "integrity": "sha512-Qd91H4liUBhwLB2h6jZ99bsxoQdhgPk6TdwnClPyTBSDAdviGPceViEgUwj+pcQDmB/rfAXAXK7MTochpHM3yQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^6.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^10.0.0", + "@octokit/request-error": "^6.0.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.0.tgz", + "integrity": "sha512-CrooV/vKCXqwLa+osmHLIMUb87brpgUqlqkPGc6iE2wCkUvTrHiXFMhAKoDDaAAYJrtKtrFTgSQTg5nObBEaew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true, + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.1.1", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "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" @@ -1497,119 +2198,463 @@ "win32" ] }, - "node_modules/@tsconfig/node20": { - "version": "20.1.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz", - "integrity": "sha512-sqgsT69YFeLWf5NtJ4Xq/xAF8p4ZQHlmGW74Nu2tD4+g5fAsposc4ZfaaPixVu4y01BEiDCWLRDCvDM5JOsRxg==", - "dev": true + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true, + "license": "MIT" }, - "node_modules/@types/bn.js": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", - "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "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==", "dev": true, + "license": "MIT", "dependencies": { - "@types/node": "*" + "conventional-changelog-angular": "^8.0.0", + "conventional-changelog-writer": "^8.0.0", + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.0.0", + "debug": "^4.0.0", + "import-from-esm": "^1.0.3", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/@types/elliptic": { - "version": "6.4.18", - "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.18.tgz", - "integrity": "sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw==", + "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-changelog-angular": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.0.0.tgz", + "integrity": "sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA==", "dev": true, + "license": "ISC", "dependencies": { - "@types/bn.js": "*" + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "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==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "meow": "^13.0.0" + }, + "bin": { + "conventional-commits-parser": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@types/node": { - "version": "22.6.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.6.1.tgz", - "integrity": "sha512-V48tCfcKb/e6cVUigLAaJDAILdMP0fUW6BidkPK4GpGjXcfbnoHasCZDwz3N3yVt5we2RHm4XTQCpv0KJz9zqw==", + "node_modules/@semantic-release/commit-analyzer/node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true + "node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz", - "integrity": "sha512-RIHOoznhA3CCfSTFiB6kBGLQtB/sox+pJ6jeFu6FxJvqL8qRxq/FfGO/UhsGgQM9oGdXkV4xUgli+dt26biB6A==", + "node_modules/@semantic-release/github": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-11.0.0.tgz", + "integrity": "sha512-Uon6G6gJD8U1JNvPm7X0j46yxNRJ8Ui6SgK4Zw5Ktu8RgjEft3BGn+l/RX1TTzhhO3/uUcKuqM+/9/ETFxWS/Q==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.7.0", - "@typescript-eslint/type-utils": "8.7.0", - "@typescript-eslint/utils": "8.7.0", - "@typescript-eslint/visitor-keys": "8.7.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "@octokit/core": "^6.0.0", + "@octokit/plugin-paginate-rest": "^11.0.0", + "@octokit/plugin-retry": "^7.0.0", + "@octokit/plugin-throttling": "^9.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "globby": "^14.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^7.0.0", + "lodash-es": "^4.17.21", + "mime": "^4.0.0", + "p-filter": "^4.0.0", + "url-join": "^5.0.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=20.8.1" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "semantic-release": ">=24.1.0" } }, - "node_modules/@typescript-eslint/parser": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.7.0.tgz", - "integrity": "sha512-lN0btVpj2unxHlNYLI//BQ7nzbMJYBVQX5+pbNXvGYazdlgYonMn4AhhHifQ+J4fGRYA/m1DjaQjx+fDetqBOQ==", + "node_modules/@semantic-release/npm": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.1.tgz", + "integrity": "sha512-/6nntGSUGK2aTOI0rHPwY3ZjgY9FkXmEHbW9Kr+62NVOsyqpKKeP0lrCH+tphv+EsNdJNmqqwijTEnVWUMQ2Nw==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.7.0", - "@typescript-eslint/types": "8.7.0", - "@typescript-eslint/typescript-estree": "8.7.0", - "@typescript-eslint/visitor-keys": "8.7.0", - "debug": "^4.3.4" + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "execa": "^9.0.0", + "fs-extra": "^11.0.0", + "lodash-es": "^4.17.21", + "nerf-dart": "^1.0.0", + "normalize-url": "^8.0.0", + "npm": "^10.5.0", + "rc": "^1.2.8", + "read-pkg": "^9.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^3.0.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=20.8.1" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true + "semantic-release": ">=20.1.0" + } + }, + "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", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@semantic-release/npm/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@semantic-release/npm/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@semantic-release/npm/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.0.1.tgz", + "integrity": "sha512-K0w+5220TM4HZTthE5dDpIuFrnkN1NfTGPidJFm04ULT1DEZ9WG89VNXN7F0c+6nMEpWgqmPvb7vY7JkB2jyyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "conventional-changelog-angular": "^8.0.0", + "conventional-changelog-writer": "^8.0.0", + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.0.0", + "debug": "^4.0.0", + "get-stream": "^7.0.0", + "import-from-esm": "^1.0.3", + "into-stream": "^7.0.0", + "lodash-es": "^4.17.21", + "read-package-up": "^11.0.0" + }, + "engines": { + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-changelog-angular": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.0.0.tgz", + "integrity": "sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "meow": "^13.0.0" + }, + "bin": { + "conventional-commits-parser": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", + "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@tsconfig/node20": { + "version": "20.1.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz", + "integrity": "sha512-sqgsT69YFeLWf5NtJ4Xq/xAF8p4ZQHlmGW74Nu2tD4+g5fAsposc4ZfaaPixVu4y01BEiDCWLRDCvDM5JOsRxg==", + "dev": true + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/elliptic": { + "version": "6.4.18", + "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.18.tgz", + "integrity": "sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw==", + "dev": true, + "dependencies": { + "@types/bn.js": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.6.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.6.1.tgz", + "integrity": "sha512-V48tCfcKb/e6cVUigLAaJDAILdMP0fUW6BidkPK4GpGjXcfbnoHasCZDwz3N3yVt5we2RHm4XTQCpv0KJz9zqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz", + "integrity": "sha512-RIHOoznhA3CCfSTFiB6kBGLQtB/sox+pJ6jeFu6FxJvqL8qRxq/FfGO/UhsGgQM9oGdXkV4xUgli+dt26biB6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.7.0", + "@typescript-eslint/type-utils": "8.7.0", + "@typescript-eslint/utils": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.7.0.tgz", + "integrity": "sha512-lN0btVpj2unxHlNYLI//BQ7nzbMJYBVQX5+pbNXvGYazdlgYonMn4AhhHifQ+J4fGRYA/m1DjaQjx+fDetqBOQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "8.7.0", + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/typescript-estree": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true } } }, @@ -1920,27 +2965,57 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "debug": "^4.3.4" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">= 14" } }, - "node_modules/algo-msgpack-with-bigint": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", - "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==", + "node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/algo-msgpack-with-bigint": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", + "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==", "license": "ISC", "engines": { "node": ">= 10" @@ -1981,11 +3056,26 @@ "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" }, + "node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -1994,7 +3084,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -2005,12 +3094,26 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "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 }, + "node_modules/argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "dev": true, + "license": "MIT" + }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", @@ -2027,6 +3130,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true, + "license": "MIT" + }, "node_modules/arraybuffer.prototype.slice": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", @@ -2086,8 +3196,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -2108,6 +3217,13 @@ } ] }, + "node_modules/before-after-hook": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz", + "integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/better-npm-audit": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/better-npm-audit/-/better-npm-audit-3.11.0.tgz", @@ -2150,11 +3266,17 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true, + "license": "MIT" + }, "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, "dependencies": { "balanced-match": "^1.0.0" } @@ -2271,6 +3393,22 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "license": "MIT" + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -2281,6 +3419,73 @@ "node": ">= 16" } }, + "node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dev": true, + "license": "ISC", + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -2296,7 +3501,6 @@ "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, "dependencies": { "color-name": "~1.1.4" }, @@ -2307,14 +3511,12 @@ "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/commander": { "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" @@ -2326,6 +3528,17 @@ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, "node_modules/compare-versions": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", @@ -2339,6 +3552,125 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-8.0.0.tgz", + "integrity": "sha512-eOvlTO6OcySPyyyk8pKz2dP4jjElYunj9hn9/s0OB+gapTO8zwS9UQWrZ1pmF2hFs3vw1xhonOLGcGjy/zgsuA==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/semver": "^7.5.5", + "conventional-commits-filter": "^5.0.0", + "handlebars": "^4.7.7", + "meow": "^13.0.0", + "semver": "^7.5.2" + }, + "bin": { + "conventional-changelog-writer": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-changelog-writer/node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conventional-commits-filter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz", + "integrity": "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/convert-hrtime": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", + "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/copyfiles": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", @@ -2433,11 +3765,28 @@ } } }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", + "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jiti": "^1.19.1" + }, + "engines": { + "node": ">=v16" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=8.2", + "typescript": ">=4" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2447,6 +3796,48 @@ "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", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dargs": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", + "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/data-view-buffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", @@ -2532,6 +3923,16 @@ "node": ">=6" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2581,14 +3982,82 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT" - }, - "node_modules/elliptic": { + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/elliptic": { "version": "6.5.7", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", @@ -2605,8 +4074,130 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/env-ci": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.1.0.tgz", + "integrity": "sha512-Z8dnwSDbV1XYM9SBF2J0GcNVvmfmfh3a49qddGIROhBoVro6MZVTji15z/sJbQ2ko2ei8n988EU1wzoLU/tF+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^8.0.0", + "java-properties": "^1.0.2" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + } + }, + "node_modules/env-ci/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/env-ci/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/env-ci/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/env-paths": { "version": "2.2.1", @@ -2617,6 +4208,19 @@ "node": ">=6" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3068,6 +4672,50 @@ "node": ">=0.10.0" } }, + "node_modules/execa": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.4.0.tgz", + "integrity": "sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.3", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.0", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3123,6 +4771,13 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", + "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "dev": true, + "license": "MIT" + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -3147,6 +4802,22 @@ } } }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -3189,6 +4860,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-versions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-6.0.0.tgz", + "integrity": "sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver-regex": "^4.0.5", + "super-regex": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", @@ -3223,7 +4924,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", @@ -3236,6 +4936,65 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/from2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/from2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/from2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "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/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3265,13 +5024,26 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "node_modules/function-timeout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-1.0.2.tgz", + "integrity": "sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "functions-have-names": "^1.2.3" @@ -3330,6 +5102,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -3359,11 +5144,53 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/git-log-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.1.tgz", + "integrity": "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "0.6.8" + } + }, + "node_modules/git-log-parser/node_modules/split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", + "dev": true, + "license": "ISC", + "dependencies": { + "through2": "~2.0.0" + } + }, + "node_modules/git-raw-commits": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", + "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^8.0.0", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/glob": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", - "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -3399,7 +5226,6 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -3411,6 +5237,22 @@ "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", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -3440,6 +5282,53 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "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", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -3465,6 +5354,28 @@ "dev": true, "license": "MIT" }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -3560,6 +5471,16 @@ "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -3570,6 +5491,19 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/hook-std": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", + "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -3582,6 +5516,44 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", + "integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -3626,6 +5598,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=16.20" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -3635,6 +5632,32 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/index-to-position": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", + "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -3651,6 +5674,16 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/internal-slot": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", @@ -3665,6 +5698,23 @@ "node": ">= 0.4" } }, + "node_modules/into-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", + "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-array-buffer": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", @@ -3782,7 +5832,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -3842,6 +5891,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -3851,6 +5910,19 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -3891,6 +5963,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -3921,6 +6006,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "text-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-typed-array": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", @@ -3936,6 +6034,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -3957,8 +6068,24 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/issue-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.1.tgz", + "integrity": "sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + } }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -4015,7 +6142,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -4027,13 +6153,33 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/js-sha256": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.11.0.tgz", - "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==" - }, - "node_modules/js-sha3": { - "version": "0.9.3", + "node_modules/java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-sha256": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.11.0.tgz", + "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==" + }, + "node_modules/js-sha3": { + "version": "0.9.3", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.3.tgz", "integrity": "sha512-BcJPCQeLg6WjEx3FE591wVAevlli8lxsxm9/FzV4HXkV49TmBH38Yvrpce6fjbADGMKFrBMGTqrVz3qPIZ88Gg==" }, @@ -4100,6 +6246,46 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -4172,24 +6358,115 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.get": { "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==", "dev": true }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true, + "license": "MIT" + }, "node_modules/loupe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", @@ -4204,7 +6481,6 @@ "version": "11.0.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz", "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==", - "dev": true, "license": "ISC", "engines": { "node": "20 || >=22" @@ -4246,6 +6522,53 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/marked": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", + "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "dev": true, + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/marked-terminal": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.1.0.tgz", + "integrity": "sha512-+pvwa14KZL74MVXjYdPR3nSInhGhNvPce/3mqLVZT2oUvt654sL1XImFuLZ1pkA866IYZ3ikDTOFUIC7XzpZZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "chalk": "^5.3.0", + "cli-highlight": "^2.1.11", + "cli-table3": "^0.6.5", + "node-emoji": "^2.1.3", + "supports-hyperlinks": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <14" + } + }, + "node_modules/marked-terminal/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -4255,6 +6578,26 @@ "node": ">= 0.10.0" } }, + "node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -4292,6 +6635,35 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/mime": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.4.tgz", + "integrity": "sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa" + ], + "license": "MIT", + "bin": { + "mime": "bin/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -4317,11 +6689,20 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -4346,6 +6727,18 @@ "dev": true, "license": "MIT" }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -4371,12 +6764,42 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", + "dev": true, + "license": "MIT" + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node_modules/node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/noms": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", @@ -4408,189 +6831,2797 @@ "semver": "bin/semver" } }, - "node_modules/npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "node_modules/normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm": { + "version": "10.8.3", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.3.tgz", + "integrity": "sha512-0IQlyAYvVtQ7uOhDFYZCGK8kkut2nh8cpAdA9E6FvRSJaTgtZRZgNjlC5ZCct//L73ygrpY93CxXpRJDtNqPVg==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/config", + "@npmcli/fs", + "@npmcli/map-workspaces", + "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/redact", + "@npmcli/run-script", + "@sigstore/tuf", + "abbrev", + "archy", + "cacache", + "chalk", + "ci-info", + "cli-columns", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmhook", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "ms", + "node-gyp", + "nopt", + "normalize-package-data", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "semver", + "spdx-expression-parse", + "ssri", + "supports-color", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which", + "write-file-atomic" + ], + "dev": true, + "license": "Artistic-2.0", + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^7.5.4", + "@npmcli/config": "^8.3.4", + "@npmcli/fs": "^3.1.1", + "@npmcli/map-workspaces": "^3.0.6", + "@npmcli/package-json": "^5.2.0", + "@npmcli/promise-spawn": "^7.0.2", + "@npmcli/redact": "^2.0.1", + "@npmcli/run-script": "^8.1.0", + "@sigstore/tuf": "^2.3.4", + "abbrev": "^2.0.0", + "archy": "~1.0.0", + "cacache": "^18.0.4", + "chalk": "^5.3.0", + "ci-info": "^4.0.0", + "cli-columns": "^4.0.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^10.4.5", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^7.0.2", + "ini": "^4.1.3", + "init-package-json": "^6.0.3", + "is-cidr": "^5.1.0", + "json-parse-even-better-errors": "^3.0.2", + "libnpmaccess": "^8.0.6", + "libnpmdiff": "^6.1.4", + "libnpmexec": "^8.1.4", + "libnpmfund": "^5.0.12", + "libnpmhook": "^10.0.5", + "libnpmorg": "^6.0.6", + "libnpmpack": "^7.0.4", + "libnpmpublish": "^9.0.9", + "libnpmsearch": "^7.0.6", + "libnpmteam": "^6.0.5", + "libnpmversion": "^6.0.3", + "make-fetch-happen": "^13.0.1", + "minimatch": "^9.0.5", + "minipass": "^7.1.1", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^10.2.0", + "nopt": "^7.2.1", + "normalize-package-data": "^6.0.2", + "npm-audit-report": "^5.0.0", + "npm-install-checks": "^6.3.0", + "npm-package-arg": "^11.0.3", + "npm-pick-manifest": "^9.1.0", + "npm-profile": "^10.0.0", + "npm-registry-fetch": "^17.1.0", + "npm-user-validate": "^2.0.1", + "p-map": "^4.0.0", + "pacote": "^18.0.6", + "parse-conflict-json": "^3.0.1", + "proc-log": "^4.2.0", + "qrcode-terminal": "^0.12.0", + "read": "^3.0.1", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "ssri": "^10.0.6", + "supports-color": "^9.4.0", + "tar": "^6.2.1", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^5.0.1", + "which": "^4.0.0", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "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, + "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", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/npm-run-all/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/npm-run-all/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/npm-run-all/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/npm-run-all/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm-run-all/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/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": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/agent": { + "version": "2.2.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "7.5.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^3.1.1", + "@npmcli/installed-package-contents": "^2.1.0", + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/metavuln-calculator": "^7.1.1", + "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.1.0", + "@npmcli/query": "^3.1.0", + "@npmcli/redact": "^2.0.0", + "@npmcli/run-script": "^8.1.0", + "bin-links": "^4.0.4", + "cacache": "^18.0.3", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^7.0.2", + "json-parse-even-better-errors": "^3.0.2", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", + "minimatch": "^9.0.4", + "nopt": "^7.2.1", + "npm-install-checks": "^6.2.0", + "npm-package-arg": "^11.0.2", + "npm-pick-manifest": "^9.0.1", + "npm-registry-fetch": "^17.0.1", + "pacote": "^18.0.6", + "parse-conflict-json": "^3.0.0", + "proc-log": "^4.2.0", + "proggy": "^2.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^10.0.6", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/config": { + "version": "8.3.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/package-json": "^5.1.1", + "ci-info": "^4.0.0", + "ini": "^4.1.2", + "nopt": "^7.2.1", + "proc-log": "^4.2.0", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/fs": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/git": { + "version": "5.0.8", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^4.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "3.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "7.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cacache": "^18.0.0", + "json-parse-even-better-errors": "^3.0.0", + "pacote": "^18.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "7.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/query": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/redact": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "8.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.0", + "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/@sigstore/bundle": { + "version": "2.3.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/core": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.3.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign": { + "version": "2.3.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "2.3.4", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^2.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/verify": { + "version": "1.2.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@tufjs/models": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/agent-base": { + "version": "7.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/aproba": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bin-links": { + "version": "4.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "18.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/chalk": { + "version": "5.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm/node_modules/chownr": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ci-info": { + "version": "4.0.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cidr-regex": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "^5.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "6.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/npm/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "4.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/diff": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/npm/node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/npm/node_modules/foreground-child": { + "version": "3.3.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/fs-minipass": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/glob": { + "version": "10.4.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "7.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "7.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "6.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/npm/node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ini": { + "version": "4.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "6.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^5.0.0", + "npm-package-arg": "^11.0.0", + "promzard": "^1.0.0", + "read": "^3.0.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/ip-address": { + "version": "9.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/npm/node_modules/ip-regex": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/is-cidr": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "^4.1.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/is-lambda": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/jackspeak": { + "version": "3.4.3", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/npm/node_modules/jsbn": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "8.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "6.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^7.5.4", + "@npmcli/installed-package-contents": "^2.1.0", + "binary-extensions": "^2.3.0", + "diff": "^5.1.0", + "minimatch": "^9.0.4", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.6", + "tar": "^6.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "8.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^7.5.4", + "@npmcli/run-script": "^8.1.0", + "ci-info": "^4.0.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.6", + "proc-log": "^4.2.0", + "read": "^3.0.1", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmfund": { + "version": "5.0.12", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^7.5.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmhook": { + "version": "10.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^17.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmorg": { + "version": "6.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^17.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "7.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^7.5.4", + "@npmcli/run-script": "^8.1.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.6" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmpublish": { + "version": "9.0.9", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "ci-info": "^4.0.0", + "normalize-package-data": "^6.0.1", + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.1", + "proc-log": "^4.2.0", + "semver": "^7.3.7", + "sigstore": "^2.2.0", + "ssri": "^10.0.6" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmsearch": { + "version": "7.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^17.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmteam": { + "version": "6.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^17.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmversion": { + "version": "6.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.7", + "@npmcli/run-script": "^8.1.0", + "json-parse-even-better-errors": "^3.0.2", + "proc-log": "^4.2.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "13.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/minipass": { + "version": "7.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-collect": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-fetch": { + "version": "3.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "10.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "7.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/normalize-package-data": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "6.3.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "11.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "8.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^6.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "9.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-profile": { + "version": "10.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^17.0.1", + "proc-log": "^4.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "17.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^2.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-user-validate": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/p-map": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/package-json-from-dist": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/npm/node_modules/pacote": { + "version": "18.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/package-json": "^5.1.0", + "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/run-script": "^8.0.0", + "cacache": "^18.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^11.0.0", + "npm-packlist": "^8.0.0", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^2.2.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/path-scurry": { + "version": "1.11.1", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/proc-log": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/proggy": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/promzard": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "^3.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/read": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-package-json-fast": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.6.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/sigstore": { + "version": "2.3.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^2.3.2", + "@sigstore/tuf": "^2.3.4", + "@sigstore/verify": "^1.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.8.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "8.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.2.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.5.0", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.18", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/npm/node_modules/ssri": { + "version": "10.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "9.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "6.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "2.2.1", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - }, - "bin": { - "npm-run-all": "bin/npm-run-all/index.js", - "run-p": "bin/run-p/index.js", - "run-s": "bin/run-s/index.js" + "@tufjs/models": "2.0.1", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.1" }, "engines": { - "node": ">= 4" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm-run-all/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/npm/node_modules/unique-filename": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "color-convert": "^1.9.0" + "unique-slug": "^4.0.0" }, "engines": { - "node": ">=4" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "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==", + "node_modules/npm/node_modules/unique-slug": { + "version": "4.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm-run-all/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", "dev": true, + "inBundle": true, + "license": "Apache-2.0", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, - "node_modules/npm-run-all/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/npm-run-all/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "node_modules/npm/node_modules/walk-up-path": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/which": { + "version": "4.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" }, "engines": { - "node": ">=4.8" + "node": "^16.13.0 || >=18.0.0" } }, - "node_modules/npm-run-all/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/npm/node_modules/which/node_modules/isexe": { + "version": "3.1.1", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=0.8.0" + "node": ">=16" } }, - "node_modules/npm-run-all/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/npm/node_modules/wrap-ansi": { + "version": "8.1.0", "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "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==", + "node_modules/npm/node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/npm-run-all/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/npm-run-all/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", "dev": true, - "bin": { - "semver": "bin/semver" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/npm-run-all/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "shebang-regex": "^1.0.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm-run-all/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "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", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/npm/node_modules/write-file-atomic": { + "version": "5.0.1", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "has-flag": "^3.0.0" + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">=4" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm-run-all/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/npm/node_modules/yallist": { + "version": "4.0.0", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" + "inBundle": true, + "license": "ISC" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, "node_modules/object-inspect": { @@ -4638,6 +9669,22 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "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", @@ -4652,7 +9699,46 @@ "word-wrap": "^1.2.5" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.8.0" + } + }, + "node_modules/p-each-series": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", + "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-filter": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz", + "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^7.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/p-limit": { @@ -4685,11 +9771,46 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.2.tgz", + "integrity": "sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-reduce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", + "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { @@ -4722,6 +9843,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true, + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4744,7 +9902,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -4759,7 +9916,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", @@ -4772,6 +9928,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", @@ -4831,6 +9997,92 @@ "node": ">=4" } }, + "node_modules/pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/polytype": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/polytype/-/polytype-0.17.0.tgz", + "integrity": "sha512-Q1y07MZqHPlGRJs8qI8bnxrQs+W3r24v25cmhbQV/lC9VNNtd+smi/2m3CUHNBDTfLtl+6SpA0EsL/J1oVsEag==", + "license": "ISC", + "engines": { + "node": ">=16.0.0" + } + }, "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", @@ -4875,72 +10127,219 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.8.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-ms": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz", + "integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true, + "license": "ISC" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-package-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", + "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-package-up/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/read-package-up/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/read-package-up/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "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==", + "node_modules/read-package-up/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", "dev": true, "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" + "dependencies": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" }, "engines": { - "node": ">=14" + "node": ">=18" }, "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "node_modules/read-package-up/node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", "dev": true, + "license": "MIT", "dependencies": { - "fast-diff": "^1.1.2" + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -4997,6 +10396,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5185,6 +10597,124 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/semantic-release": { + "version": "24.1.2", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.1.2.tgz", + "integrity": "sha512-hvEJ7yI97pzJuLsDZCYzJgmRxF8kiEJvNZhf0oiZQcexw+Ycjy4wbdsn/sVMURgNCu8rwbAXJdBRyIxM4pe32g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@semantic-release/commit-analyzer": "^13.0.0-beta.1", + "@semantic-release/error": "^4.0.0", + "@semantic-release/github": "^11.0.0", + "@semantic-release/npm": "^12.0.0", + "@semantic-release/release-notes-generator": "^14.0.0-beta.1", + "aggregate-error": "^5.0.0", + "cosmiconfig": "^9.0.0", + "debug": "^4.0.0", + "env-ci": "^11.0.0", + "execa": "^9.0.0", + "figures": "^6.0.0", + "find-versions": "^6.0.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^3.0.0", + "hosted-git-info": "^8.0.0", + "import-from-esm": "^1.3.1", + "lodash-es": "^4.17.21", + "marked": "^12.0.0", + "marked-terminal": "^7.0.0", + "micromatch": "^4.0.2", + "p-each-series": "^3.0.0", + "p-reduce": "^3.0.0", + "read-package-up": "^11.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^4.0.0", + "signale": "^1.2.1", + "yargs": "^17.5.1" + }, + "bin": { + "semantic-release": "bin/semantic-release.js" + }, + "engines": { + "node": ">=20.8.1" + } + }, + "node_modules/semantic-release/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/semantic-release/node_modules/hosted-git-info": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.0.tgz", + "integrity": "sha512-4nw3vOVR+vHUOT8+U4giwe2tcGv+R3pwwRidUe67DoMBTjhrfr6rZYJVVwdkBE+Um050SG+X9tf0Jo4fOpn01w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/semantic-release/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/semantic-release/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/semantic-release/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/semantic-release/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -5198,6 +10728,35 @@ "node": ">=10" } }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver-regex": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", + "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -5234,7 +10793,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5246,7 +10804,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -5289,13 +10846,144 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "license": "ISC", "engines": { "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/signale/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/signale/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/signale/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/signale/node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "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": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/slice-ansi": { @@ -5315,6 +11003,16 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -5324,6 +11022,13 @@ "node": ">=0.10.0" } }, + "node_modules/spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", + "dev": true, + "license": "MIT" + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -5356,6 +11061,16 @@ "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -5370,6 +11085,50 @@ "dev": true, "license": "MIT" }, + "node_modules/stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-combiner2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/stream-combiner2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/stream-combiner2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -5380,7 +11139,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5395,7 +11153,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -5477,7 +11234,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5490,7 +11246,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -5508,6 +11263,19 @@ "node": ">=4" } }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -5521,6 +11289,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/super-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-1.0.0.tgz", + "integrity": "sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-timeout": "^1.0.1", + "time-span": "^5.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5533,6 +11318,23 @@ "node": ">=8" } }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -5599,6 +11401,61 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/temp-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/tempy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", + "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^3.0.0", + "temp-dir": "^3.0.0", + "type-fest": "^2.12.2", + "unique-string": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/test-exclude": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", @@ -5675,12 +11532,55 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "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 }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, "node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -5721,6 +11621,22 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/time-span": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", + "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "convert-hrtime": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -5787,6 +11703,19 @@ "node": ">=8.0" } }, + "node_modules/traverse": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", + "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -5842,6 +11771,19 @@ "node": ">= 0.8.0" } }, + "node_modules/type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typed-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", @@ -5929,6 +11871,20 @@ "node": ">=14.17" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -5951,6 +11907,62 @@ "dev": true, "license": "MIT" }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universal-user-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/untildify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", @@ -5960,6 +11972,16 @@ "node": ">=8" } }, + "node_modules/upath": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -5969,6 +11991,16 @@ "punycode": "^2.1.0" } }, + "node_modules/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -6571,7 +12603,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -6643,6 +12674,13 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -6665,7 +12703,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -6741,6 +12778,28 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", + "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 330f254..7105e07 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { - "name": "@algorandfoundation/algo-ts-testing", + "name": "@algorandfoundation/algorand-typescript-testing", "version": "1.0.0", - "description": "", + "description": "A library which allows you to execute Algorand TypeScript code locally under a test context either emulating or mocking AVM behaviour.", + "private": false, "main": "index.js", "types": "src/index.ts", "scripts": { @@ -17,26 +18,19 @@ "build:4-copy-pkg-json": "tstk copy-package-json -c", "build:5-copy-readme": "copyfiles ./README.md ./dist", "watch": "rollup -c -w --configPlugin typescript", - "install-local-packages": "npm run algo-ts && npm run pyua-ts", - "algo-ts": "run-s algo-ts:*", - "algo-ts:build": "cd ../puya-ts/packages/algo-ts && npm run build", - "algo-ts:install": "npm i -D @algorandfoundation/algo-ts@../puya-ts/packages/algo-ts/dist", - "pyua-ts": "run-s pyua-ts:*", - "pyua-ts:build": "cd ../puya-ts && npm run build", - "pyua-ts:install": "npm i -D @algorandfoundation/puya-ts@../puya-ts/dist", - "xtest": "vitest run", - "xtest:coverage": "vitest run --coverage", - "xtest:ci": "vitest run --coverage --reporter junit --outputFile test-results.xml" + "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" }, "devDependencies": { - "@algorandfoundation/algo-ts": "file:../puya-ts/packages/algo-ts/dist", - "@algorandfoundation/algo-ts-testing": "file:./dist", - "@algorandfoundation/puya-ts": "file:../puya-ts/dist", + "@commitlint/cli": "^19.5.0", + "@commitlint/config-conventional": "^19.5.0", "@eslint/eslintrc": "3.1.0", "@eslint/js": "9.11.1", "@makerx/eslint-config": "4.0.0", "@makerx/prettier-config": "2.0.1", - "@makerx/ts-toolkit": "4.0.0-beta.20", + "@makerx/ts-toolkit": "4.0.0-beta.21", "@rollup/plugin-commonjs": "28.0.0", "@rollup/plugin-json": "6.1.0", "@rollup/plugin-node-resolve": "15.3.0", @@ -48,6 +42,7 @@ "@typescript-eslint/parser": "8.7.0", "@vitest/coverage-v8": "2.1.1", "better-npm-audit": "3.11.0", + "conventional-changelog-conventionalcommits": "^8.0.0", "copyfiles": "2.4.1", "eslint": "9.11.1", "eslint-config-prettier": "^9.1.0", @@ -56,17 +51,18 @@ "prettier": "3.3.3", "rimraf": "6.0.1", "rollup": "^4.22.4", + "semantic-release": "^24.1.1", "tsx": "4.19.1", "typescript": "^5.6.2", "vitest": "2.1.1" }, "peerDependencies": { - "@algorandfoundation/algo-ts": "*", - "@algorandfoundation/puya-ts": "*", "tslib": "^2.6.2" }, "dependencies": { + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.2", "@algorandfoundation/algokit-utils": "^6.2.1", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.5", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", diff --git a/src/abi-metadata.ts b/src/abi-metadata.ts index b51596f..544611a 100644 --- a/src/abi-metadata.ts +++ b/src/abi-metadata.ts @@ -1,5 +1,5 @@ -import { Contract } from '@algorandfoundation/algo-ts' -import { AbiMethodConfig, BareMethodConfig, CreateOptions, OnCompleteActionStr } from '@algorandfoundation/algo-ts/arc4' +import { Contract } from '@algorandfoundation/algorand-typescript' +import { AbiMethodConfig, BareMethodConfig, CreateOptions, OnCompleteActionStr } from '@algorandfoundation/algorand-typescript/arc4' import { DeliberateAny } from './typescript-helpers' export interface AbiMetadata { diff --git a/src/constants.ts b/src/constants.ts index c8a0742..e6d28d6 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,4 +1,4 @@ -import { Bytes } from '@algorandfoundation/algo-ts' +import { Bytes } from '@algorandfoundation/algorand-typescript' export const UINT64_SIZE = 64 export const UINT512_SIZE = 512 diff --git a/src/context-helpers/internal-context.ts b/src/context-helpers/internal-context.ts index 0f57064..8a2c8e6 100644 --- a/src/context-helpers/internal-context.ts +++ b/src/context-helpers/internal-context.ts @@ -1,4 +1,4 @@ -import { internal } from '@algorandfoundation/algo-ts' +import { internal } from '@algorandfoundation/algorand-typescript' import { AccountData } from '../impl/account' import { ApplicationData } from '../impl/application' import { AssetData } from '../impl/asset' diff --git a/src/decode-logs.ts b/src/decode-logs.ts index f7efc07..83b73af 100644 --- a/src/decode-logs.ts +++ b/src/decode-logs.ts @@ -1,4 +1,4 @@ -import { internal } from '@algorandfoundation/algo-ts' +import { internal } from '@algorandfoundation/algorand-typescript' export type LogDecoding = 'i' | 's' | 'b' diff --git a/src/errors.ts b/src/errors.ts index 18f0378..abb462c 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,4 +1,4 @@ -import { internal } from '@algorandfoundation/algo-ts' +import { internal } from '@algorandfoundation/algorand-typescript' export class NotImplementedError extends Error { constructor(feature: string) { diff --git a/src/impl/account.ts b/src/impl/account.ts index 38815a0..78dc416 100644 --- a/src/impl/account.ts +++ b/src/impl/account.ts @@ -1,4 +1,4 @@ -import { Account, Application, Asset, bytes, internal, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, Asset, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { DEFAULT_ACCOUNT_MIN_BALANCE, ZERO_ADDRESS } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { Mutable } from '../typescript-helpers' diff --git a/src/impl/acct-params.ts b/src/impl/acct-params.ts index dadec58..4632f01 100644 --- a/src/impl/acct-params.ts +++ b/src/impl/acct-params.ts @@ -1,4 +1,4 @@ -import { Account, gtxn, internal, uint64 } from '@algorandfoundation/algo-ts' +import { Account, gtxn, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asMaybeUint64Cls } from '../util' diff --git a/src/impl/app-params.ts b/src/impl/app-params.ts index af1f9b7..6d4d0db 100644 --- a/src/impl/app-params.ts +++ b/src/impl/app-params.ts @@ -1,4 +1,4 @@ -import { Account, Application, Bytes, bytes, gtxn, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, Bytes, bytes, gtxn, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asMaybeUint64Cls, asUint64 } from '../util' diff --git a/src/impl/application.ts b/src/impl/application.ts index 5d72b4b..2d17daa 100644 --- a/src/impl/application.ts +++ b/src/impl/application.ts @@ -1,4 +1,4 @@ -import { Account, Application, Bytes, bytes, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, Bytes, bytes, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' import { ALWAYS_APPROVE_TEAL_PROGRAM } from '../constants' import { lazyContext } from '../context-helpers/internal-context' diff --git a/src/impl/asset-holding.ts b/src/impl/asset-holding.ts index 0580eba..d028e16 100644 --- a/src/impl/asset-holding.ts +++ b/src/impl/asset-holding.ts @@ -1,4 +1,4 @@ -import { Account, Asset, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Asset, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asBigInt } from '../util' import { AssetHolding as AssetHoldingData } from './account' diff --git a/src/impl/asset-params.ts b/src/impl/asset-params.ts index fbc5917..be4d48b 100644 --- a/src/impl/asset-params.ts +++ b/src/impl/asset-params.ts @@ -1,4 +1,4 @@ -import { Account, Asset, Bytes, bytes, gtxn, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Asset, Bytes, bytes, gtxn, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asMaybeUint64Cls, asUint64 } from '../util' diff --git a/src/impl/asset.ts b/src/impl/asset.ts index 04a94b1..3ac36b7 100644 --- a/src/impl/asset.ts +++ b/src/impl/asset.ts @@ -1,4 +1,4 @@ -import { Account, Asset, bytes, internal, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Asset, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asBigInt, asUint64 } from '../util' import { Mutable } from '../typescript-helpers' diff --git a/src/impl/crypto.ts b/src/impl/crypto.ts index c9457c1..093d0e5 100644 --- a/src/impl/crypto.ts +++ b/src/impl/crypto.ts @@ -1,4 +1,4 @@ -import { Bytes, bytes, internal, gtxn, arc4 } from '@algorandfoundation/algo-ts' +import { Bytes, bytes, internal, gtxn, arc4 } 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' diff --git a/src/impl/global.ts b/src/impl/global.ts index 167371f..8616266 100644 --- a/src/impl/global.ts +++ b/src/impl/global.ts @@ -1,4 +1,4 @@ -import { Account, Application, Bytes, bytes, internal, op, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, Bytes, bytes, internal, op, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { DEFAULT_ACCOUNT_MIN_BALANCE, diff --git a/src/impl/gtxn.ts b/src/impl/gtxn.ts index 9d24afa..fb491b1 100644 --- a/src/impl/gtxn.ts +++ b/src/impl/gtxn.ts @@ -1,4 +1,4 @@ -import { Account, Application, arc4, Asset, bytes, internal, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, arc4, Asset, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asUint64, asUint64Cls } from '../util' diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts index be86470..8f6c4ea 100644 --- a/src/impl/inner-transactions.ts +++ b/src/impl/inner-transactions.ts @@ -1,4 +1,4 @@ -import { Account, Application, arc4, Asset, bytes, internal, itxn, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, arc4, Asset, bytes, internal, itxn, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' import { ApplicationTransaction, AssetConfigTransaction, diff --git a/src/impl/itxn.ts b/src/impl/itxn.ts index aa09daa..5a89368 100644 --- a/src/impl/itxn.ts +++ b/src/impl/itxn.ts @@ -1,4 +1,4 @@ -import { Account, Application, arc4, Asset, bytes, internal, itxn, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, arc4, Asset, bytes, internal, itxn, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asBytes, asBytesCls, asUint64, asUint64Cls } from '../util' import { getApp } from './app-params' diff --git a/src/impl/pure.ts b/src/impl/pure.ts index 0d1ce58..a37442c 100644 --- a/src/impl/pure.ts +++ b/src/impl/pure.ts @@ -1,4 +1,4 @@ -import { biguint, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { biguint, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT64, MAX_UINT8, UINT64_SIZE } from '../constants' import { notImplementedError } from '../errors' import { asBigUint, asBytes, asMaybeBytesCls, asMaybeUint64Cls, asUint64Cls, binaryStringToBytes } from '../util' diff --git a/src/impl/scratch.ts b/src/impl/scratch.ts index 7efebd1..cc2e3ab 100644 --- a/src/impl/scratch.ts +++ b/src/impl/scratch.ts @@ -1,4 +1,4 @@ -import { bytes, internal, uint64 } from '@algorandfoundation/algo-ts' +import { bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' export const Scratch: internal.opTypes.ScratchType = { diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index 04dbcaa..d37d493 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -10,7 +10,7 @@ import { TransactionType, uint64, Uint64, -} from '@algorandfoundation/algo-ts' +} from '@algorandfoundation/algorand-typescript' import { MAX_ITEMS_IN_LOG } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { Mutable, ObjectKeys } from '../typescript-helpers' diff --git a/src/impl/txn.ts b/src/impl/txn.ts index 2709a54..cd21e5f 100644 --- a/src/impl/txn.ts +++ b/src/impl/txn.ts @@ -1,4 +1,4 @@ -import { Account, Application, arc4, Asset, bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, arc4, Asset, bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asNumber, asUint64, asUint64Cls } from '../util' // import { diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 2cd0f11..f02076b 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -1,7 +1,8 @@ -import { internal } from '@algorandfoundation/algo-ts' +import { internal } from '@algorandfoundation/algorand-typescript' import { MAX_UINT64 } from './constants' import { DeliberateAny } from './typescript-helpers' import { nameOfType } from './util' + export { attachAbiMetadata } from './abi-metadata' export function switchableValue(x: unknown): bigint | string | boolean { diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index a50145b..a013b3f 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -1,4 +1,4 @@ -import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, internal } from '@algorandfoundation/algo-ts' +import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, internal } from '@algorandfoundation/algorand-typescript' import { getAbiMetadata, hasAbiMetadata } from '../abi-metadata' import { lazyContext } from '../context-helpers/internal-context' import { AccountCls } from '../impl/account' diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index b18aa8c..5daf650 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -1,4 +1,4 @@ -import { Account, Application, Asset, BaseContract, internal } from '@algorandfoundation/algo-ts' +import { Account, Application, Asset, BaseContract, internal } from '@algorandfoundation/algorand-typescript' import { MAX_UINT64 } from '../constants' import { AccountData, AssetHolding } from '../impl/account' import { ApplicationData } from '../impl/application' diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 64e9b0a..42e27a2 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -1,4 +1,4 @@ -import { bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algo-ts' +import { bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' import { lazyContext } from '../context-helpers/internal-context' import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 5cc9d09..26a67f2 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -1,4 +1,4 @@ -import { Account, Application, Asset, Bytes, bytes, internal, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, Asset, Bytes, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' import { captureMethodConfig } from './abi-metadata' import { DecodedLogs, LogDecoding } from './decode-logs' diff --git a/src/test-transformer/index.ts b/src/test-transformer/index.ts index 47bc33b..beb0585 100644 --- a/src/test-transformer/index.ts +++ b/src/test-transformer/index.ts @@ -1,22 +1,52 @@ -import type ts from 'typescript' import { registerPTypes, typeRegistry } from '@algorandfoundation/puya-ts' +import type ts from 'typescript' import type { DeliberateAny } from '../typescript-helpers' import { SourceFileVisitor } from './visitors' -const includes: string[] = ['.algo.ts', '.spec.ts'] -const programTransformer = { - type: 'program', - factory(program: ts.Program): ts.TransformerFactory { +export interface TransformerConfig { + includeExt: string[] + testingPackageName: string +} +const defaultTransformerConfig: TransformerConfig = { + includeExt: ['.algo.ts', '.spec.ts'], + testingPackageName: '@algorandfoundation/algorand-typescript-testing', +} + +// const programTransformer = { +// type: 'program', +// factory(program: ts.Program): ts.TransformerFactory { +// registerPTypes(typeRegistry) +// return (context) => { +// return (sourceFile) => { +// if (!includes.some((i) => sourceFile.fileName.endsWith(i))) return sourceFile +// return new SourceFileVisitor(context, sourceFile, program).result() +// } +// } +// }, +// } +const createProgramFactory = (config: TransformerConfig) => { + function programFactory(program: ts.Program): ts.TransformerFactory { registerPTypes(typeRegistry) return (context) => { return (sourceFile) => { - if (!includes.some((i) => sourceFile.fileName.endsWith(i))) return sourceFile - return new SourceFileVisitor(context, sourceFile, program).result() + 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 = programTransformer as DeliberateAny +export const puyaTsTransformer: ts.TransformerFactory & + ((config: Partial) => ts.TransformerFactory) = programTransformer as DeliberateAny diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 0cd0aee..6fc7415 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -1,16 +1,15 @@ -import ts from 'typescript' - import { FunctionPType } from '@algorandfoundation/puya-ts' +import ts from 'typescript' import type { DeliberateAny } from '../typescript-helpers' import { getPropertyNameAsString } from './helpers' const factory = ts.factory export const nodeFactory = { - importHelpers() { + importHelpers(testingPackageName: string) { return factory.createImportDeclaration( undefined, factory.createImportClause(false, undefined, factory.createNamespaceImport(factory.createIdentifier('runtimeHelpers'))), - factory.createStringLiteral('@algorandfoundation/algo-ts-testing/runtime-helpers'), + factory.createStringLiteral(`${testingPackageName}/runtime-helpers`), undefined, ) }, diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index 2744702..c701cc7 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -1,5 +1,6 @@ +import { anyPType, ContractClassPType, FunctionPType, PType, SourceLocation, typeRegistry, TypeResolver } from '@algorandfoundation/puya-ts' import ts from 'typescript' -import { ContractClassPType, FunctionPType, PType, SourceLocation, TypeResolver, anyPType, typeRegistry } from '@algorandfoundation/puya-ts' +import { TransformerConfig } from './index' import { nodeFactory } from './node-factory' import { supportedBinaryOpString, supportedPrefixUnaryOpString } from './supported-binary-op-string' @@ -17,6 +18,7 @@ export class SourceFileVisitor { private context: ts.TransformationContext, private sourceFile: ts.SourceFile, program: ts.Program, + private config: TransformerConfig, ) { const typeResolver = new TypeResolver(program.getTypeChecker(), program.getCurrentDirectory()) @@ -39,7 +41,7 @@ export class SourceFileVisitor { const updatedSourceFile = ts.visitNode(this.sourceFile, this.visit) as ts.SourceFile return factory.updateSourceFile(updatedSourceFile, [ - nodeFactory.importHelpers(), + nodeFactory.importHelpers(this.config.testingPackageName), ...updatedSourceFile.statements, ...this.helper.additionalStatements, ]) diff --git a/src/util.ts b/src/util.ts index 6f3a108..c298be2 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,4 @@ -import { internal, bytes } from '@algorandfoundation/algo-ts' +import { internal, bytes } from '@algorandfoundation/algorand-typescript' import { randomBytes } from 'crypto' import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT8, UINT512_SIZE } from './constants' import { DeliberateAny } from './typescript-helpers' diff --git a/src/value-generators/avm.ts b/src/value-generators/avm.ts index 586bfbc..810db87 100644 --- a/src/value-generators/avm.ts +++ b/src/value-generators/avm.ts @@ -1,4 +1,4 @@ -import { Account, Application, Asset, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { Account, Application, Asset, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' import { randomBytes } from 'crypto' import { MAX_BYTES_SIZE, MAX_UINT64, ZERO_ADDRESS } from '../constants' diff --git a/src/value-generators/txn.ts b/src/value-generators/txn.ts index 82a3aab..e935816 100644 --- a/src/value-generators/txn.ts +++ b/src/value-generators/txn.ts @@ -1,4 +1,4 @@ -import { gtxn, internal } from '@algorandfoundation/algo-ts' +import { gtxn, internal } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { ApplicationTransaction, diff --git a/tests/artifacts/created-app-asset/contract.algo.ts b/tests/artifacts/created-app-asset/contract.algo.ts index 0747372..d532f13 100644 --- a/tests/artifacts/created-app-asset/contract.algo.ts +++ b/tests/artifacts/created-app-asset/contract.algo.ts @@ -1,4 +1,4 @@ -import { arc4, assert, Bytes, gtxn, op, uint64 } from '@algorandfoundation/algo-ts' +import { arc4, assert, Bytes, gtxn, op, uint64 } from '@algorandfoundation/algorand-typescript' export class AppExpectingEffects extends arc4.Contract { @arc4.abimethod() diff --git a/tests/artifacts/state-ops/contract.algo.ts b/tests/artifacts/state-ops/contract.algo.ts index 698beee..5363c82 100644 --- a/tests/artifacts/state-ops/contract.algo.ts +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -15,7 +15,7 @@ import { Txn, Uint64, uint64, -} from '@algorandfoundation/algo-ts' +} from '@algorandfoundation/algorand-typescript' function get_1st_ref_index(): uint64 { return op.btoi(Txn.applicationArgs(1)) diff --git a/tests/avm-invoker.ts b/tests/avm-invoker.ts index 4c606f5..f2e07d6 100644 --- a/tests/avm-invoker.ts +++ b/tests/avm-invoker.ts @@ -1,4 +1,4 @@ -import { internal, uint64 } from '@algorandfoundation/algo-ts' +import { internal, uint64 } from '@algorandfoundation/algorand-typescript' import * as algokit from '@algorandfoundation/algokit-utils' import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import { ABIAppCallArg, ABIReturn } from '@algorandfoundation/algokit-utils/types/app' diff --git a/tests/crypto-op-codes.spec.ts b/tests/crypto-op-codes.spec.ts index 0a76f42..50adbed 100644 --- a/tests/crypto-op-codes.spec.ts +++ b/tests/crypto-op-codes.spec.ts @@ -1,4 +1,4 @@ -import { Bytes, internal, op as publicOps, uint64 } from '@algorandfoundation/algo-ts' +import { Bytes, internal, op as publicOps, uint64 } from '@algorandfoundation/algorand-typescript' import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import algosdk from 'algosdk' diff --git a/tests/primitives/biguint.spec.ts b/tests/primitives/biguint.spec.ts index 5afce81..b21694f 100644 --- a/tests/primitives/biguint.spec.ts +++ b/tests/primitives/biguint.spec.ts @@ -1,5 +1,5 @@ -import type { biguint } from '@algorandfoundation/algo-ts' -import { BigUint, Bytes, internal, Uint64 } from '@algorandfoundation/algo-ts' +import type { biguint } from '@algorandfoundation/algorand-typescript' +import { BigUint, Bytes, internal, Uint64 } from '@algorandfoundation/algorand-typescript' import type { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { describe, expect, it } from 'vitest' import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' diff --git a/tests/primitives/bytes.spec.ts b/tests/primitives/bytes.spec.ts index 3b3721b..9377b1c 100644 --- a/tests/primitives/bytes.spec.ts +++ b/tests/primitives/bytes.spec.ts @@ -1,4 +1,4 @@ -import { bytes, Bytes, internal } from '@algorandfoundation/algo-ts' +import { bytes, Bytes, internal } from '@algorandfoundation/algorand-typescript' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { describe, expect, it } from 'vitest' import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' diff --git a/tests/primitives/uint64.spec.ts b/tests/primitives/uint64.spec.ts index 6711294..4c1b490 100644 --- a/tests/primitives/uint64.spec.ts +++ b/tests/primitives/uint64.spec.ts @@ -1,4 +1,4 @@ -import { internal, uint64, Uint64 } from '@algorandfoundation/algo-ts' +import { internal, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { describe, expect, it } from 'vitest' import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' diff --git a/tests/pure-op-codes.spec.ts b/tests/pure-op-codes.spec.ts index 27770bc..2035af9 100644 --- a/tests/pure-op-codes.spec.ts +++ b/tests/pure-op-codes.spec.ts @@ -1,4 +1,4 @@ -import { BigUint, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algo-ts' +import { BigUint, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' diff --git a/tests/references/asset.spec.ts b/tests/references/asset.spec.ts index 9020bfd..d01ac70 100644 --- a/tests/references/asset.spec.ts +++ b/tests/references/asset.spec.ts @@ -1,4 +1,4 @@ -import { Account, Bytes, Uint64 } from '@algorandfoundation/algo-ts' +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' diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 8f86d1f..43c3b30 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -1,4 +1,4 @@ -import { Account, arc4, bytes, Bytes, internal, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algo-ts' +import { Account, arc4, bytes, Bytes, internal, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' diff --git a/tests/util.ts b/tests/util.ts index ab436f9..af67b5e 100644 --- a/tests/util.ts +++ b/tests/util.ts @@ -1,4 +1,4 @@ -import { Bytes, bytes, internal } from '@algorandfoundation/algo-ts' +import { Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' import { createHash } from 'crypto' export const padUint8Array = (arr: Uint8Array, padSize: number): Uint8Array => { diff --git a/tsconfig.json b/tsconfig.json index a00766d..26a3a72 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,12 +2,17 @@ "extends": "@tsconfig/node20/tsconfig.json", "compilerOptions": { "noEmit": true, - "target": "ES2020", + "target": "ES2023", "module": "ESNext", + "lib": ["ES2023"], "moduleResolution": "Bundler", "resolveJsonModule": true, - "esModuleInterop": true + "esModuleInterop": true, + "paths": { + "@algorandfoundation/algorand-typescript-testing": ["./src/index.ts"], + "@algorandfoundation/algorand-typescript-testing/runtime-helpers": ["./src/runtime-helpers.ts"], + } }, "include": ["src/**/*.ts", "scripts/**/*.ts", "examples/**/*.ts", "rollup.config.ts", "tests/**/*.ts", "vitest.config.mts", "eslint.config.mjs" ], - "exclude": ["examples/**/*.spec.ts"] + "exclude": [] } diff --git a/vitest.config.mts b/vitest.config.mts index 46d7902..e82b3bd 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -9,12 +9,7 @@ export default defineConfig({ esbuild: {}, plugins: [ typescript({ - target: 'ES2022', - tsconfig: false, - exclude: ['node_modules'], - compilerOptions: { - lib: ['es2023'], - }, + tsconfig: './tsconfig.json', transformers: { before: [puyaTsTransformer], }, From 17a7c366460c900cd8dcb2a3400dbfbd431c2f70 Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Wed, 2 Oct 2024 15:52:09 -0700 Subject: [PATCH 09/85] docs: Add starter readme text --- readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/readme.md b/readme.md index e69de29..97c79dd 100644 --- a/readme.md +++ b/readme.md @@ -0,0 +1,3 @@ +# @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. \ No newline at end of file From 308ed900164d1b6e1f923e4340898bb90a807ef4 Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Wed, 2 Oct 2024 15:52:39 -0700 Subject: [PATCH 10/85] build: Reduce max eslint warnings --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7105e07..4d9c25d 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "lint:fix": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix", "build": "run-s build:*", "build:0-clean": "rimraf dist coverage", - "build:1-lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" --max-warnings 10", + "build:1-lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" --max-warnings 0", "build:2-check-types": "tsc -p tsconfig.json", "build:3-build": "rollup -c --configPlugin typescript", "build:4-copy-pkg-json": "tstk copy-package-json -c", From 00c59240441175f4c12022cf0a5cf865cc36c9bf Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Thu, 3 Oct 2024 10:25:07 -0700 Subject: [PATCH 11/85] build: Fix test transformer export --- .tstoolkitrc.ts | 2 +- rollup.config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.tstoolkitrc.ts b/.tstoolkitrc.ts index 27cbfce..4058bc4 100644 --- a/.tstoolkitrc.ts +++ b/.tstoolkitrc.ts @@ -10,7 +10,7 @@ const config: TsToolkitConfig = { exports: { '.': 'index.ts', './runtime-helpers': 'runtime-helpers.ts', - './test-transformer': 'test-transformer.ts', + './test-transformer/index': 'test-transformer.ts', }, }, } diff --git a/rollup.config.ts b/rollup.config.ts index 8c7c2f8..22bda1b 100644 --- a/rollup.config.ts +++ b/rollup.config.ts @@ -8,7 +8,7 @@ const config: RollupOptions = { input: { index: 'src/index.ts', 'runtime-helpers': 'src/runtime-helpers.ts', - 'test-transformer': 'src/test-transformer/index.ts', + 'test-transformer/index': 'src/test-transformer/index.ts', }, output: [ { From 6a7dacde747bf6c327cd8c474d612d9adb7afe6a Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Thu, 3 Oct 2024 13:13:19 -0700 Subject: [PATCH 12/85] fix: Actually fix test transformer export path --- .tstoolkitrc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.tstoolkitrc.ts b/.tstoolkitrc.ts index 4058bc4..b9c2800 100644 --- a/.tstoolkitrc.ts +++ b/.tstoolkitrc.ts @@ -10,7 +10,7 @@ const config: TsToolkitConfig = { exports: { '.': 'index.ts', './runtime-helpers': 'runtime-helpers.ts', - './test-transformer/index': 'test-transformer.ts', + './test-transformer': 'test-transformer/index.ts', }, }, } From fdbc13bc870e1cf29971ec17c84dfcd2127b2ab1 Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Thu, 3 Oct 2024 15:52:45 -0700 Subject: [PATCH 13/85] feat: Add equality testers setup function for comparing algots primitives --- src/set-up.ts | 31 +++++++++++++++++++++++++++++++ vitest.setup.ts | 6 ++++++ 2 files changed, 37 insertions(+) create mode 100644 src/set-up.ts create mode 100644 vitest.setup.ts diff --git a/src/set-up.ts b/src/set-up.ts new file mode 100644 index 0000000..c565c94 --- /dev/null +++ b/src/set-up.ts @@ -0,0 +1,31 @@ +import { internal } from '@algorandfoundation/algorand-typescript' + +type Tester = (this: TesterContext, a: unknown, b: unknown, customTesters: Array) => boolean | undefined +interface TesterContext { + equals: (a: unknown, b: unknown, customTesters?: Array, strictCheck?: boolean) => boolean +} +interface ExpectObj { + addEqualityTesters: (testers: Array) => void +} + +function addEqualityTesters(expectObj: ExpectObj) { + expectObj.addEqualityTesters([ + function (this: TesterContext, subject, test, customTesters): boolean | undefined { + const subjectIsPrimitive = subject instanceof internal.primitives.AlgoTsPrimitiveCls + const testIsPrimitive = test instanceof internal.primitives.AlgoTsPrimitiveCls + if (subjectIsPrimitive && testIsPrimitive) { + return this.equals(subject.valueOf(), test.valueOf(), customTesters) + } else if (subjectIsPrimitive === testIsPrimitive) { + // Neither is primitive + return undefined + } else { + // One is primitive, one is not + return false + } + }, + ]) +} + +export function setUpTests({ expect }: { expect: ExpectObj }) { + addEqualityTesters(expect) +} diff --git a/vitest.setup.ts b/vitest.setup.ts new file mode 100644 index 0000000..bf5e858 --- /dev/null +++ b/vitest.setup.ts @@ -0,0 +1,6 @@ +import { expect } from 'vitest' +import { setUpTests } from './src/set-up' + +export function setup() { + setUpTests({ expect }) +} From 941251400ccedc839054114fcd5a5b2b528abc38 Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Thu, 3 Oct 2024 15:55:42 -0700 Subject: [PATCH 14/85] fix: ARC4 contracts should log the return value of an abi method, encoded as bytes and prefixed with a specific byte pattern detailed by arc4 --- src/abi-metadata.ts | 4 +-- src/constants.ts | 2 ++ src/decode-logs.ts | 8 ++--- src/impl/transactions.ts | 6 +++- src/subcontexts/contract-context.ts | 49 +++++++++++++++++--------- src/subcontexts/transaction-context.ts | 24 ++++++------- 6 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/abi-metadata.ts b/src/abi-metadata.ts index 544611a..d11dc57 100644 --- a/src/abi-metadata.ts +++ b/src/abi-metadata.ts @@ -1,4 +1,4 @@ -import { Contract } from '@algorandfoundation/algorand-typescript' +import { BaseContract, Contract } from '@algorandfoundation/algorand-typescript' import { AbiMethodConfig, BareMethodConfig, CreateOptions, OnCompleteActionStr } from '@algorandfoundation/algorand-typescript/arc4' import { DeliberateAny } from './typescript-helpers' @@ -50,7 +50,7 @@ export const hasAbiMetadata = (contract: T): boolean => { ) } -export const getAbiMetadata = (contract: T, methodName: string): AbiMetadata => { +export const getAbiMetadata = (contract: T, methodName: string): AbiMetadata => { const contractClass = contract.constructor as { new (): T } const s = Object.getOwnPropertySymbols(contractClass).find((s) => s.toString() === AbiMetaSymbol.toString()) const metadatas: Record = ( diff --git a/src/constants.ts b/src/constants.ts index e6d28d6..d25fa25 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -35,3 +35,5 @@ export const LOGIC_DATA_PREFIX = Bytes('ProgData') //number: minimum transaction fee export const MIN_TXN_FEE = 1000 + +export const ABI_RETURN_VALUE_LOG_PREFIX = Bytes.fromHex('151F7C75') diff --git a/src/decode-logs.ts b/src/decode-logs.ts index 83b73af..2fa74f0 100644 --- a/src/decode-logs.ts +++ b/src/decode-logs.ts @@ -1,4 +1,4 @@ -import { internal } from '@algorandfoundation/algorand-typescript' +import { bytes, op } from '@algorandfoundation/algorand-typescript' export type LogDecoding = 'i' | 's' | 'b' @@ -6,13 +6,13 @@ export type DecodedLog = T extends 'i' ? bigint : T exten export type DecodedLogs = { [Index in keyof T]: DecodedLog } & { length: T['length'] } -export function decodeLogs(logs: Uint8Array[], decoding: T): DecodedLogs { +export function decodeLogs(logs: bytes[], decoding: T): DecodedLogs { return logs.map((log, i) => { switch (decoding[i]) { case 'i': - return internal.encodingUtil.uint8ArrayToBigInt(log) + return op.btoi(log) case 's': - return internal.encodingUtil.uint8ArrayToUtf8(log) + return log.toString() default: return log } diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index d37d493..dc4c613 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -11,7 +11,7 @@ import { uint64, Uint64, } from '@algorandfoundation/algorand-typescript' -import { MAX_ITEMS_IN_LOG } from '../constants' +import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_ITEMS_IN_LOG } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { Mutable, ObjectKeys } from '../typescript-helpers' import { asBytes, asMaybeBytesCls, asMaybeUint64Cls, asNumber, asUint64Cls, combineIntoMaxBytePages, getRandomBytes } from '../util' @@ -334,6 +334,10 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl } this.#appLogs.push(asBytes(value)) } + /* @internal */ + logArc4ReturnValue(value: internal.primitives.StubBytesCompat): void { + this.appendLog(ABI_RETURN_VALUE_LOG_PREFIX.concat(asBytes(value))) + } } export type Transaction = diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index a013b3f..71d12ac 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -1,5 +1,5 @@ import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, internal } from '@algorandfoundation/algorand-typescript' -import { getAbiMetadata, hasAbiMetadata } from '../abi-metadata' +import { getAbiMetadata } from '../abi-metadata' import { lazyContext } from '../context-helpers/internal-context' import { AccountCls } from '../impl/account' import { ApplicationCls } from '../impl/application' @@ -96,11 +96,24 @@ function isTransaction(obj: unknown): obj is Transaction { export class ContractContext { create(type: IConstructor, ...args: DeliberateAny[]): T { - const proxy = new Proxy(type, this.getContractProxyHandler()) + Object.getPrototypeOf(type) + const proxy = new Proxy(type, this.getContractProxyHandler(this.isArc4(type))) return new proxy(...args) } - private getContractProxyHandler(): ProxyHandler> { + private isArc4(type: IConstructor): boolean { + 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') + } + return this.isArc4(proto) + } + + private getContractProxyHandler(isArc4: boolean): ProxyHandler> { const onConstructed = (instance: BaseContract) => { const states = extractStates(instance) @@ -111,31 +124,35 @@ export class ContractContext { } return { construct(target, args) { - let isArc4 = false const instance = new Proxy(new target(...args), { get(target, prop, receiver) { const orig = Reflect.get(target, prop, receiver) - if (isArc4 || prop === 'approvalProgram' || prop === 'clearStateProgram') { + const isProgramMethod = prop === 'approvalProgram' || prop === 'clearStateProgram' + if (isArc4 || isProgramMethod) { return (...args: DeliberateAny[]): DeliberateAny => { const app = lazyContext.ledger.getApplicationForContract(receiver) const { transactions, ...appCallArgs } = extractArraysFromArgs(args) - const abiMetadata = getAbiMetadata(receiver, prop as string) - const txns = [ - ...(transactions ?? []), - lazyContext.any.txn.applicationCall({ - appId: app, - ...appCallArgs, - onCompletion: (abiMetadata?.allowActions ?? [])[0], - }), - ] - return lazyContext.txn.ensureScope(txns).execute(() => (orig as DeliberateAny).apply(target, args)) + const abiMetadata = getAbiMetadata(target, prop as string) + const appTxn = lazyContext.any.txn.applicationCall({ + appId: app, + ...appCallArgs, + // TODO: This needs to be specifiable by the test code + onCompletion: (abiMetadata?.allowActions ?? [])[0], + }) + const txns = [...(transactions ?? []), appTxn] + return lazyContext.txn.ensureScope(txns).execute(() => { + const returnValue = (orig as DeliberateAny).apply(target, args) + if (isArc4) { + appTxn.logArc4ReturnValue(returnValue) + } + return returnValue + }) } } return orig }, }) onConstructed(instance) - isArc4 = hasAbiMetadata(instance as Contract) return instance }, diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 42e27a2..e1cfd4f 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -3,6 +3,16 @@ import algosdk from 'algosdk' import { lazyContext } from '../context-helpers/internal-context' import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' import { testInvariant } from '../errors' +import { + ApplicationInnerTxn, + AssetConfigInnerTxn, + AssetFreezeInnerTxn, + AssetTransferInnerTxn, + createInnerTxn, + KeyRegistrationInnerTxn, + PaymentInnerTxn, +} from '../impl/inner-transactions' +import { InnerTxn, InnerTxnFields } from '../impl/itxn' import { AllTransactionFields, ApplicationTransaction, @@ -14,16 +24,6 @@ import { Transaction, } from '../impl/transactions' import { asBigInt, asNumber, asUint64 } from '../util' -import { InnerTxn, InnerTxnFields } from '../impl/itxn' -import { - ApplicationInnerTxn, - AssetConfigInnerTxn, - AssetFreezeInnerTxn, - AssetTransferInnerTxn, - createInnerTxn, - KeyRegistrationInnerTxn, - PaymentInnerTxn, -} from '../impl/inner-transactions' function ScopeGenerator(dispose: () => void) { function* internal() { @@ -119,8 +119,8 @@ export class TransactionContext { } else { logs = lazyContext.getApplicationData(appId).appLogs } - const rawLogs = logs.map((l) => internal.primitives.toExternalValue(l)) - return decodeLogs(rawLogs, decoding) + + return decodeLogs(logs, decoding) } } From 74baf7a88851441e70c6fc601d085fee0acf9e7a Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Thu, 3 Oct 2024 18:55:53 -0700 Subject: [PATCH 15/85] feat: Expand equality comparers to allow uint64/biguint to numeric literal comparison --- src/set-up.ts | 24 ++++++++++++++++++------ src/test-transformer/index.ts | 12 ------------ vitest.config.mts | 9 +++------ vitest.setup.ts | 6 +++--- 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/set-up.ts b/src/set-up.ts index c565c94..ee171f9 100644 --- a/src/set-up.ts +++ b/src/set-up.ts @@ -10,22 +10,34 @@ interface ExpectObj { function addEqualityTesters(expectObj: ExpectObj) { expectObj.addEqualityTesters([ - function (this: TesterContext, subject, test, customTesters): boolean | undefined { + function IsSamePrimitiveTypeAndValue(this: TesterContext, subject, test, customTesters): boolean | undefined { const subjectIsPrimitive = subject instanceof internal.primitives.AlgoTsPrimitiveCls const testIsPrimitive = test instanceof internal.primitives.AlgoTsPrimitiveCls + const isSamePrimitive = subjectIsPrimitive && test instanceof Object.getPrototypeOf(subject).constructor if (subjectIsPrimitive && testIsPrimitive) { + if (!isSamePrimitive) return false return this.equals(subject.valueOf(), test.valueOf(), customTesters) - } else if (subjectIsPrimitive === testIsPrimitive) { - // Neither is primitive + } + // Defer to other testers + return undefined + }, + function NumericPrimitiveIsNumericLiteral(this: TesterContext, subject, test, customTesters): boolean | undefined { + if (subject instanceof internal.primitives.Uint64Cls || subject instanceof internal.primitives.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 + } else if (test instanceof internal.primitives.Uint64Cls || test instanceof internal.primitives.BigUintCls) { + const subjectValue = typeof subject === 'bigint' ? subject : typeof subject === 'number' ? BigInt(subject) : undefined + if (subjectValue !== undefined) return this.equals(subjectValue, test.valueOf(), customTesters) return undefined - } else { - // One is primitive, one is not - return false } + // Defer to other testers + return undefined }, ]) } export function setUpTests({ expect }: { expect: ExpectObj }) { + console.log('setting up stuff') addEqualityTesters(expect) } diff --git a/src/test-transformer/index.ts b/src/test-transformer/index.ts index beb0585..6b79f8e 100644 --- a/src/test-transformer/index.ts +++ b/src/test-transformer/index.ts @@ -12,18 +12,6 @@ const defaultTransformerConfig: TransformerConfig = { testingPackageName: '@algorandfoundation/algorand-typescript-testing', } -// const programTransformer = { -// type: 'program', -// factory(program: ts.Program): ts.TransformerFactory { -// registerPTypes(typeRegistry) -// return (context) => { -// return (sourceFile) => { -// if (!includes.some((i) => sourceFile.fileName.endsWith(i))) return sourceFile -// return new SourceFileVisitor(context, sourceFile, program).result() -// } -// } -// }, -// } const createProgramFactory = (config: TransformerConfig) => { function programFactory(program: ts.Program): ts.TransformerFactory { registerPTypes(typeRegistry) diff --git a/vitest.config.mts b/vitest.config.mts index e82b3bd..401a8fb 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -3,10 +3,10 @@ import { defineConfig } from 'vitest/config' import { puyaTsTransformer } from './src/test-transformer' export default defineConfig({ - resolve: { - conditions: ['dev'], - }, esbuild: {}, + test: { + setupFiles: 'vitest.setup.ts', + }, plugins: [ typescript({ tsconfig: './tsconfig.json', @@ -15,7 +15,4 @@ export default defineConfig({ }, }), ], - test: { - globals: true, - }, }) diff --git a/vitest.setup.ts b/vitest.setup.ts index bf5e858..b7a7689 100644 --- a/vitest.setup.ts +++ b/vitest.setup.ts @@ -1,6 +1,6 @@ -import { expect } from 'vitest' +import { beforeAll, expect } from 'vitest' import { setUpTests } from './src/set-up' -export function setup() { +beforeAll(() => { setUpTests({ expect }) -} +}) From 2972cc678aae9c91006b6ed0a77cb9cec1b4352b Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Thu, 3 Oct 2024 19:03:55 -0700 Subject: [PATCH 16/85] test: Fix test assertions --- examples/calculator/contract.algo.ts | 5 ++--- examples/calculator/contract.spec.ts | 4 ++-- examples/hello-world-abi/contract.spec.ts | 13 ++++++++++--- examples/rollup.config.ts | 1 + src/set-up.ts | 1 - 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/calculator/contract.algo.ts b/examples/calculator/contract.algo.ts index 3180789..421937d 100644 --- a/examples/calculator/contract.algo.ts +++ b/examples/calculator/contract.algo.ts @@ -1,5 +1,4 @@ -import type { uint64 } from '@algorandfoundation/algorand-typescript' -import { assert, Bytes, Contract, err, log, op, Txn, Uint64 } from '@algorandfoundation/algorand-typescript' +import { assert, BaseContract, Bytes, err, log, op, Txn, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' const ADD = Uint64(1) const SUB = Uint64(2) @@ -13,7 +12,7 @@ function itoa(i: uint64): string { } return itoa(i / radix).concat(digits.at(i % radix).toString()) } -export default class MyContract extends Contract { +export default class MyContract extends BaseContract { public approvalProgram(): boolean { const numArgs = Txn.numAppArgs let a: uint64, b: uint64, action: uint64 diff --git a/examples/calculator/contract.spec.ts b/examples/calculator/contract.spec.ts index a57ccd1..4d5a122 100644 --- a/examples/calculator/contract.spec.ts +++ b/examples/calculator/contract.spec.ts @@ -38,8 +38,8 @@ describe('Calculator', () => { const [left, right, outcome] = ctx.exportLogs(application.id, 'i', 'i', 's') - expect(left).toBe(2n) - expect(right).toBe(3n) + expect(left).toEqual(Uint64(2)) + expect(right).toEqual(3n) expect(outcome).toBe('2 + 3 = 5') expect(result).toBe(true) }) diff --git a/examples/hello-world-abi/contract.spec.ts b/examples/hello-world-abi/contract.spec.ts index 32ad91b..55e85b9 100644 --- a/examples/hello-world-abi/contract.spec.ts +++ b/examples/hello-world-abi/contract.spec.ts @@ -1,6 +1,7 @@ -import { assert, TransactionType } from '@algorandfoundation/algorand-typescript' +import { assert, Bytes, TransactionType } 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 HelloWorldContract from './contract.algo' describe('HelloWorldContract', () => { @@ -14,7 +15,10 @@ describe('HelloWorldContract', () => { assert(ctx.txn.lastActive.type === TransactionType.ApplicationCall, 'Last txn must be app') expect(result).toBe('Bananas') - expect(ctx.exportLogs(ctx.txn.lastActive.appId.id, 's')).toStrictEqual([result]) + const bananasBytes = Bytes('Bananas') + const abiLog = ABI_RETURN_VALUE_LOG_PREFIX.concat(bananasBytes) + const logs = ctx.exportLogs(ctx.txn.lastActive.appId.id, 's', 'b') + expect(logs).toStrictEqual([result, abiLog]) }) it('logs the returned value when sayHello is called', async () => { const contract = ctx.contract.create(HelloWorldContract) @@ -22,6 +26,9 @@ describe('HelloWorldContract', () => { assert(ctx.txn.lastActive.type === TransactionType.ApplicationCall, 'Last txn must be app') expect(result).toBe('Hello John Doe') - expect(ctx.exportLogs(ctx.txn.lastActive.appId.id, 's')).toStrictEqual([result]) + const helloBytes = Bytes('Hello John Doe') + const abiLog = ABI_RETURN_VALUE_LOG_PREFIX.concat(helloBytes) + const logs = ctx.exportLogs(ctx.txn.lastActive.appId.id, 's', 'b') + expect(logs).toStrictEqual([result, abiLog]) }) }) diff --git a/examples/rollup.config.ts b/examples/rollup.config.ts index 455a291..bc04ab8 100644 --- a/examples/rollup.config.ts +++ b/examples/rollup.config.ts @@ -6,6 +6,7 @@ import { puyaTsTransformer } from '../src/test-transformer' const config: RollupOptions = { input: [ + 'examples/calculator/contract.algo.ts', 'examples/hello-world-abi/contract.algo.ts', 'examples/hello-world/contract.algo.ts', 'examples/auction/contract.algo.ts', diff --git a/src/set-up.ts b/src/set-up.ts index ee171f9..1cf8fe9 100644 --- a/src/set-up.ts +++ b/src/set-up.ts @@ -38,6 +38,5 @@ function addEqualityTesters(expectObj: ExpectObj) { } export function setUpTests({ expect }: { expect: ExpectObj }) { - console.log('setting up stuff') addEqualityTesters(expect) } From 209a327a6c6a109e0289735f1a7a65c5bfb9535a Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Thu, 3 Oct 2024 19:04:57 -0700 Subject: [PATCH 17/85] fix: Use toBytes to convert unknown value to bytes instead of asBytes, and don't log undefined/void --- src/impl/transactions.ts | 15 ++++++++++++--- src/subcontexts/contract-context.ts | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index dc4c613..f0b23ae 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -14,7 +14,16 @@ import { import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_ITEMS_IN_LOG } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { Mutable, ObjectKeys } from '../typescript-helpers' -import { asBytes, asMaybeBytesCls, asMaybeUint64Cls, asNumber, asUint64Cls, combineIntoMaxBytePages, getRandomBytes } from '../util' +import { + asBytes, + asMaybeBytesCls, + asMaybeUint64Cls, + asNumber, + asUint64Cls, + combineIntoMaxBytePages, + getRandomBytes, + toBytes, +} from '../util' const baseDefaultFields = () => ({ sender: lazyContext.defaultSender, @@ -335,8 +344,8 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl this.#appLogs.push(asBytes(value)) } /* @internal */ - logArc4ReturnValue(value: internal.primitives.StubBytesCompat): void { - this.appendLog(ABI_RETURN_VALUE_LOG_PREFIX.concat(asBytes(value))) + logArc4ReturnValue(value: unknown): void { + this.appendLog(ABI_RETURN_VALUE_LOG_PREFIX.concat(toBytes(value))) } } diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 71d12ac..851e51e 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -142,7 +142,7 @@ export class ContractContext { const txns = [...(transactions ?? []), appTxn] return lazyContext.txn.ensureScope(txns).execute(() => { const returnValue = (orig as DeliberateAny).apply(target, args) - if (isArc4) { + if (isArc4 && returnValue !== undefined) { appTxn.logArc4ReturnValue(returnValue) } return returnValue From 0fc5cbd33418fc899e59804a586235e981b472c2 Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Fri, 4 Oct 2024 10:41:31 -0700 Subject: [PATCH 18/85] fix: Don't log result of program method even on arc4 contracts --- src/subcontexts/contract-context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 851e51e..79946e0 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -142,7 +142,7 @@ export class ContractContext { const txns = [...(transactions ?? []), appTxn] return lazyContext.txn.ensureScope(txns).execute(() => { const returnValue = (orig as DeliberateAny).apply(target, args) - if (isArc4 && returnValue !== undefined) { + if (!isProgramMethod && isArc4 && returnValue !== undefined) { appTxn.logArc4ReturnValue(returnValue) } return returnValue From db9b74a69895cb2af088b581b076e4a4a7e1cf69 Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Fri, 4 Oct 2024 10:41:52 -0700 Subject: [PATCH 19/85] chore: Update ignored and excluded dirs --- .gitignore | 3 +++ .idea/algorand-typescript-testing.iml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 3813a4e..929222c 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,6 @@ out/ .env.test.local .env.production.local .env.local + + +examples/debug-out/ diff --git a/.idea/algorand-typescript-testing.iml b/.idea/algorand-typescript-testing.iml index 24643cc..6409d10 100644 --- a/.idea/algorand-typescript-testing.iml +++ b/.idea/algorand-typescript-testing.iml @@ -3,6 +3,8 @@ + + From c92edef04c0f9daebddfc1baf6cf9f6203cfaf6d Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Wed, 9 Oct 2024 20:49:13 -0700 Subject: [PATCH 20/85] feat: Add test equality comparers to enable test assertions with algo-ts types and update tests to use these --- package-lock.json | 509 ++++++++++++------------ package.json | 22 +- readme.md | 7 +- src/collections/custom-key-map.ts | 67 ++++ src/constants.ts | 6 +- src/context-helpers/internal-context.ts | 7 +- src/impl/account.ts | 17 +- src/impl/application.ts | 11 +- src/impl/asset-holding.ts | 2 +- src/impl/asset.ts | 13 +- src/impl/base.ts | 24 ++ src/impl/crypto.ts | 12 +- src/impl/global.ts | 8 +- src/impl/pure.ts | 52 ++- src/runtime-helpers.ts | 14 +- src/set-up.ts | 49 ++- src/subcontexts/ledger-context.ts | 12 +- src/test-execution-context.ts | 20 +- src/util.ts | 23 +- src/value-generators/avm.ts | 22 +- tests/avm-invoker.ts | 16 +- tests/crypto-op-codes.spec.ts | 40 +- tests/primitives/biguint.spec.ts | 221 +++++----- tests/primitives/bytes.spec.ts | 20 +- tests/primitives/uint64.spec.ts | 35 +- tests/pure-op-codes.spec.ts | 284 ++++++------- tests/state-op-codes.spec.ts | 94 ++--- tests/util.ts | 24 +- 28 files changed, 897 insertions(+), 734 deletions(-) create mode 100644 src/collections/custom-key-map.ts create mode 100644 src/impl/base.ts diff --git a/package-lock.json b/package-lock.json index 5fcf5f7..47a0266 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "1.0.0", "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.2", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.5", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.9", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", @@ -22,7 +22,7 @@ "@commitlint/cli": "^19.5.0", "@commitlint/config-conventional": "^19.5.0", "@eslint/eslintrc": "3.1.0", - "@eslint/js": "9.11.1", + "@eslint/js": "9.12.0", "@makerx/eslint-config": "4.0.0", "@makerx/prettier-config": "2.0.1", "@makerx/ts-toolkit": "4.0.0-beta.21", @@ -32,24 +32,24 @@ "@rollup/plugin-typescript": "^12.1.0", "@tsconfig/node20": "20.1.4", "@types/elliptic": "^6.4.18", - "@types/node": "22.6.1", - "@typescript-eslint/eslint-plugin": "8.7.0", - "@typescript-eslint/parser": "8.7.0", - "@vitest/coverage-v8": "2.1.1", + "@types/node": "22.7.5", + "@typescript-eslint/eslint-plugin": "8.8.1", + "@typescript-eslint/parser": "8.8.1", + "@vitest/coverage-v8": "2.1.2", "better-npm-audit": "3.11.0", "conventional-changelog-conventionalcommits": "^8.0.0", "copyfiles": "2.4.1", - "eslint": "9.11.1", + "eslint": "9.12.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "npm-run-all": "4.1.5", "prettier": "3.3.3", "rimraf": "6.0.1", - "rollup": "^4.22.4", - "semantic-release": "^24.1.1", + "rollup": "^4.24.0", + "semantic-release": "^24.1.2", "tsx": "4.19.1", "typescript": "^5.6.2", - "vitest": "2.1.1" + "vitest": "2.1.2" }, "peerDependencies": { "tslib": "^2.6.2" @@ -103,17 +103,17 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.2", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.2.tgz", - "integrity": "sha512-ULqsgvaLp8L3P0dgukjQSfYRvGkc7S/wVeOxO+w5+GVJ7+kqQbAtCgRhqdYXjc4Mle6VKsSc87GW/zgXGVZlHg==", + "version": "0.0.1-alpha.9", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.9.tgz", + "integrity": "sha512-F5Sungkl0z6y1nu0VGN9ZSkAxHemTM/JIycdcXH60rWinZrQLUXTGVkPvrrQ0h+OyZrgBSdTOsJ7xh9l10Ylzw==", "peerDependencies": { "tslib": "^2.6.2" } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0-alpha.5", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.5.tgz", - "integrity": "sha512-OFzquX8EpzeRWH2+2FDnfymCe5lBpP+ZrvqPtXNy2cYaq7YE8hzT+pU2bujvDH3IeP8G0vVv8rDISyCXR4R96A==", + "version": "1.0.0-alpha.14", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.14.tgz", + "integrity": "sha512-OVfc6Jh6YDG6W61YMB3O02pNSwJSKRO9P2kAmaAWImQgp1yCEZYu2N2VxJbeml09J8DJ62Vd1GkQ4P7gYD3pvg==", "bundleDependencies": [ "typescript" ], @@ -147,7 +147,7 @@ } }, "node_modules/@algorandfoundation/puya-ts/node_modules/typescript": { - "version": "5.6.2", + "version": "5.6.3", "inBundle": true, "license": "Apache-2.0", "bin": { @@ -1338,9 +1338,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.11.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", - "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", + "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", "dev": true, "license": "MIT", "engines": { @@ -1370,6 +1370,30 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@humanfs/core": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", + "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", + "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.0", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -1384,9 +1408,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "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": { @@ -1991,208 +2015,224 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -2553,10 +2593,11 @@ } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", @@ -2566,9 +2607,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.6.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.6.1.tgz", - "integrity": "sha512-V48tCfcKb/e6cVUigLAaJDAILdMP0fUW6BidkPK4GpGjXcfbnoHasCZDwz3N3yVt5we2RHm4XTQCpv0KJz9zqw==", + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2596,17 +2637,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz", - "integrity": "sha512-RIHOoznhA3CCfSTFiB6kBGLQtB/sox+pJ6jeFu6FxJvqL8qRxq/FfGO/UhsGgQM9oGdXkV4xUgli+dt26biB6A==", + "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==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.7.0", - "@typescript-eslint/type-utils": "8.7.0", - "@typescript-eslint/utils": "8.7.0", - "@typescript-eslint/visitor-keys": "8.7.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", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -2630,16 +2671,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.7.0.tgz", - "integrity": "sha512-lN0btVpj2unxHlNYLI//BQ7nzbMJYBVQX5+pbNXvGYazdlgYonMn4AhhHifQ+J4fGRYA/m1DjaQjx+fDetqBOQ==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.1.tgz", + "integrity": "sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.7.0", - "@typescript-eslint/types": "8.7.0", - "@typescript-eslint/typescript-estree": "8.7.0", - "@typescript-eslint/visitor-keys": "8.7.0", + "@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", "debug": "^4.3.4" }, "engines": { @@ -2659,14 +2700,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz", - "integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==", + "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==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.7.0", - "@typescript-eslint/visitor-keys": "8.7.0" + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/visitor-keys": "8.8.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2677,14 +2718,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.7.0.tgz", - "integrity": "sha512-tl0N0Mj3hMSkEYhLkjREp54OSb/FI6qyCzfiiclvJvOqre6hsZTGSnHtmFLDU8TIM62G7ygEa1bI08lcuRwEnQ==", + "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==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.7.0", - "@typescript-eslint/utils": "8.7.0", + "@typescript-eslint/typescript-estree": "8.8.1", + "@typescript-eslint/utils": "8.8.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -2702,9 +2743,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz", - "integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.1.tgz", + "integrity": "sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==", "dev": true, "license": "MIT", "engines": { @@ -2716,14 +2757,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz", - "integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==", + "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==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.7.0", - "@typescript-eslint/visitor-keys": "8.7.0", + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/visitor-keys": "8.8.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2745,16 +2786,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz", - "integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.1.tgz", + "integrity": "sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.7.0", - "@typescript-eslint/types": "8.7.0", - "@typescript-eslint/typescript-estree": "8.7.0" + "@typescript-eslint/scope-manager": "8.8.1", + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/typescript-estree": "8.8.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2768,13 +2809,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz", - "integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.1.tgz", + "integrity": "sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/types": "8.8.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -2786,9 +2827,9 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.1.tgz", - "integrity": "sha512-md/A7A3c42oTT8JUHSqjP5uKTWJejzUW4jalpvs+rZ27gsURsMU8DEb+8Jf8C6Kj2gwfSHJqobDNBuoqlm0cFw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.2.tgz", + "integrity": "sha512-b7kHrFrs2urS0cOk5N10lttI8UdJ/yP3nB4JYTREvR5o18cR99yPpK4gK8oQgI42BVv0ILWYUSYB7AXkAUDc0g==", "dev": true, "license": "MIT", "dependencies": { @@ -2809,8 +2850,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "2.1.1", - "vitest": "2.1.1" + "@vitest/browser": "2.1.2", + "vitest": "2.1.2" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -2819,14 +2860,14 @@ } }, "node_modules/@vitest/expect": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.1.tgz", - "integrity": "sha512-YeueunS0HiHiQxk+KEOnq/QMzlUuOzbU1Go+PgAsHvvv3tUkJPm9xWt+6ITNTlzsMXUjmgm5T+U7KBPK2qQV6w==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.2.tgz", + "integrity": "sha512-FEgtlN8mIUSEAAnlvn7mP8vzaWhEaAEvhSXCqrsijM7K6QqjB11qoRZYEd4AKSCDz8p0/+yH5LzhZ47qt+EyPg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "2.1.1", - "@vitest/utils": "2.1.1", + "@vitest/spy": "2.1.2", + "@vitest/utils": "2.1.2", "chai": "^5.1.1", "tinyrainbow": "^1.2.0" }, @@ -2835,9 +2876,9 @@ } }, "node_modules/@vitest/mocker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.1.tgz", - "integrity": "sha512-LNN5VwOEdJqCmJ/2XJBywB11DLlkbY0ooDJW3uRX5cZyYCrc4PI/ePX0iQhE3BiEGiQmK4GE7Q/PqCkkaiPnrA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.2.tgz", + "integrity": "sha512-ExElkCGMS13JAJy+812fw1aCv2QO/LBK6CyO4WOPAzLTmve50gydOlWhgdBJPx2ztbADUq3JVI0C5U+bShaeEA==", "dev": true, "license": "MIT", "dependencies": { @@ -2849,7 +2890,7 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/spy": "2.1.1", + "@vitest/spy": "2.1.2", "msw": "^2.3.5", "vite": "^5.0.0" }, @@ -2873,9 +2914,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.1.tgz", - "integrity": "sha512-SjxPFOtuINDUW8/UkElJYQSFtnWX7tMksSGW0vfjxMneFqxVr8YJ979QpMbDW7g+BIiq88RAGDjf7en6rvLPPQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.2.tgz", + "integrity": "sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==", "dev": true, "license": "MIT", "dependencies": { @@ -2886,13 +2927,13 @@ } }, "node_modules/@vitest/runner": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.1.tgz", - "integrity": "sha512-uTPuY6PWOYitIkLPidaY5L3t0JJITdGTSwBtwMjKzo5O6RCOEncz9PUN+0pDidX8kTHYjO0EwUIvhlGpnGpxmA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.2.tgz", + "integrity": "sha512-UCsPtvluHO3u7jdoONGjOSil+uON5SSvU9buQh3lP7GgUXHp78guN1wRmZDX4wGK6J10f9NUtP6pO+SFquoMlw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "2.1.1", + "@vitest/utils": "2.1.2", "pathe": "^1.1.2" }, "funding": { @@ -2900,13 +2941,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.1.tgz", - "integrity": "sha512-BnSku1WFy7r4mm96ha2FzN99AZJgpZOWrAhtQfoxjUU5YMRpq1zmHRq7a5K9/NjqonebO7iVDla+VvZS8BOWMw==", + "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.1", + "@vitest/pretty-format": "2.1.2", "magic-string": "^0.30.11", "pathe": "^1.1.2" }, @@ -2915,9 +2956,9 @@ } }, "node_modules/@vitest/spy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.1.tgz", - "integrity": "sha512-ZM39BnZ9t/xZ/nF4UwRH5il0Sw93QnZXd9NAZGRpIgj0yvVwPpLd702s/Cx955rGaMlyBQkZJ2Ir7qyY48VZ+g==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.2.tgz", + "integrity": "sha512-GSUi5zoy+abNRJwmFhBDC0yRuVUn8WMlQscvnbbXdKLXX9dE59YbfwXxuJ/mth6eeqIzofU8BB5XDo/Ns/qK2A==", "dev": true, "license": "MIT", "dependencies": { @@ -2928,13 +2969,13 @@ } }, "node_modules/@vitest/utils": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.1.tgz", - "integrity": "sha512-Y6Q9TsI+qJ2CC0ZKj6VBb+T8UPz593N113nnUykqwANqhgf3QkZeHFlusgKLTqrnVHbj/XDKZcDHol+dxVT+rQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.2.tgz", + "integrity": "sha512-zMO2KdYy6mx56btx9JvAqAZ6EyS3g49krMPPrgOp1yxGZiA93HumGk+bZ5jIZtOg5/VBYl5eBmGRQHqq4FG6uQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.1", + "@vitest/pretty-format": "2.1.2", "loupe": "^3.1.1", "tinyrainbow": "^1.2.0" }, @@ -4416,9 +4457,9 @@ } }, "node_modules/eslint": { - "version": "9.11.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz", - "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==", + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", + "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", "dev": true, "license": "MIT", "dependencies": { @@ -4427,11 +4468,11 @@ "@eslint/config-array": "^0.18.0", "@eslint/core": "^0.6.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.11.1", + "@eslint/js": "9.12.0", "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", + "@humanwhocodes/retry": "^0.3.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -4439,9 +4480,9 @@ "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4451,13 +4492,11 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { @@ -4521,9 +4560,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", + "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4549,13 +4588,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, - "license": "MIT" - }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4567,9 +4599,9 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4592,15 +4624,15 @@ } }, "node_modules/espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", + "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" + "eslint-visitor-keys": "^4.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4610,9 +4642,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5073,16 +5105,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -5901,15 +5923,6 @@ "node": ">=8" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -6468,14 +6481,11 @@ "license": "MIT" }, "node_modules/loupe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", - "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } + "license": "MIT" }, "node_modules/lru-cache": { "version": "11.0.1", @@ -10493,12 +10503,13 @@ } }, "node_modules/rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -10508,22 +10519,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", "fsevents": "~2.3.2" } }, @@ -12018,9 +12029,9 @@ } }, "node_modules/vite": { - "version": "5.4.7", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz", - "integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==", + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", + "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12078,9 +12089,9 @@ } }, "node_modules/vite-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.1.tgz", - "integrity": "sha512-N/mGckI1suG/5wQI35XeR9rsMsPqKXzq1CdUndzVstBj/HvyxxGctwnK6WX43NGt5L3Z5tcRf83g4TITKJhPrA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.2.tgz", + "integrity": "sha512-HPcGNN5g/7I2OtPjLqgOtCRu/qhVvBxTUD3qzitmL0SrG1cWFzxzhMDWussxSbrRYWqnKf8P2jiNhPMSN+ymsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12530,19 +12541,19 @@ } }, "node_modules/vitest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.1.tgz", - "integrity": "sha512-97We7/VC0e9X5zBVkvt7SGQMGrRtn3KtySFQG5fpaMlS+l62eeXRQO633AYhSTC3z7IMebnPPNjGXVGNRFlxBA==", + "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.1", - "@vitest/mocker": "2.1.1", - "@vitest/pretty-format": "^2.1.1", - "@vitest/runner": "2.1.1", - "@vitest/snapshot": "2.1.1", - "@vitest/spy": "2.1.1", - "@vitest/utils": "2.1.1", + "@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", @@ -12553,7 +12564,7 @@ "tinypool": "^1.0.0", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "2.1.1", + "vite-node": "2.1.2", "why-is-node-running": "^2.3.0" }, "bin": { @@ -12568,8 +12579,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.1.1", - "@vitest/ui": "2.1.1", + "@vitest/browser": "2.1.2", + "@vitest/ui": "2.1.2", "happy-dom": "*", "jsdom": "*" }, diff --git a/package.json b/package.json index 4d9c25d..9c6441a 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@commitlint/cli": "^19.5.0", "@commitlint/config-conventional": "^19.5.0", "@eslint/eslintrc": "3.1.0", - "@eslint/js": "9.11.1", + "@eslint/js": "9.12.0", "@makerx/eslint-config": "4.0.0", "@makerx/prettier-config": "2.0.1", "@makerx/ts-toolkit": "4.0.0-beta.21", @@ -37,32 +37,32 @@ "@rollup/plugin-typescript": "^12.1.0", "@tsconfig/node20": "20.1.4", "@types/elliptic": "^6.4.18", - "@types/node": "22.6.1", - "@typescript-eslint/eslint-plugin": "8.7.0", - "@typescript-eslint/parser": "8.7.0", - "@vitest/coverage-v8": "2.1.1", + "@types/node": "22.7.5", + "@typescript-eslint/eslint-plugin": "8.8.1", + "@typescript-eslint/parser": "8.8.1", + "@vitest/coverage-v8": "2.1.2", "better-npm-audit": "3.11.0", "conventional-changelog-conventionalcommits": "^8.0.0", "copyfiles": "2.4.1", - "eslint": "9.11.1", + "eslint": "9.12.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "npm-run-all": "4.1.5", "prettier": "3.3.3", "rimraf": "6.0.1", - "rollup": "^4.22.4", - "semantic-release": "^24.1.1", + "rollup": "^4.24.0", + "semantic-release": "^24.1.2", "tsx": "4.19.1", "typescript": "^5.6.2", - "vitest": "2.1.1" + "vitest": "2.1.2" }, "peerDependencies": { "tslib": "^2.6.2" }, "dependencies": { - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.2", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.9", "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.5", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", diff --git a/readme.md b/readme.md index 97c79dd..a18c1c1 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,8 @@ # @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. \ No newline at end of file +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/src/collections/custom-key-map.ts b/src/collections/custom-key-map.ts new file mode 100644 index 0000000..709290e --- /dev/null +++ b/src/collections/custom-key-map.ts @@ -0,0 +1,67 @@ +import { Account, internal } from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { DeliberateAny } from '../typescript-helpers' + +type Primitive = number | bigint | string | boolean +export abstract class CustomKeyMap implements Map { + #keySerializer: (key: TKey) => Primitive + #map = new Map() + + constructor(keySerializer: (key: TKey) => number | bigint | string) { + this.#keySerializer = keySerializer + } + + clear(): void { + this.#map.clear() + } + delete(key: TKey): boolean { + return this.#map.delete(this.#keySerializer(key)) + } + forEach(callbackfn: (value: TValue, key: TKey, map: Map) => void, thisArg?: DeliberateAny): void { + for (const [key, value] of this.#map.values()) { + callbackfn.call(thisArg ?? this, value, key, this) + } + } + get(key: TKey): TValue | undefined { + return this.#map.get(this.#keySerializer(key))?.[1] + } + has(key: TKey): boolean { + return this.#map.has(this.#keySerializer(key)) + } + set(key: TKey, value: TValue): this { + this.#map.set(this.#keySerializer(key), [key, value]) + return this + } + get size(): number { + return this.#map.size + } + entries(): MapIterator<[TKey, TValue]> { + return this.#map.values() + } + *keys(): MapIterator { + for (const [key] of this.#map.values()) { + yield key + } + } + *values(): MapIterator { + for (const [, value] of this.#map.values()) { + yield value + } + } + [Symbol.iterator](): MapIterator<[TKey, TValue]> { + return this.#map.values() + } + get [Symbol.toStringTag](): string { + return this.constructor.name + } +} + +export class AccountMap extends CustomKeyMap { + constructor() { + super(AccountMap.getAddressStrFromAccount) + } + + private static getAddressStrFromAccount = (acc: Account) => { + return encodingUtil.uint8ArrayToHex(internal.primitives.BytesCls.fromCompat(acc.bytes).asUint8Array()) + } +} diff --git a/src/constants.ts b/src/constants.ts index d25fa25..88e8bc1 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -22,7 +22,8 @@ export const DEFAULT_GLOBAL_GENESIS_HASH = Bytes( ) // algorand encoded address of 32 zero bytes -export const ZERO_ADDRESS = Bytes('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ') +export const ZERO_ADDRESS_B32 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ' +export const ZERO_ADDRESS = Bytes.fromBase32(ZERO_ADDRESS_B32) /** "\x09" # pragma version 9 @@ -37,3 +38,6 @@ export const LOGIC_DATA_PREFIX = Bytes('ProgData') export const MIN_TXN_FEE = 1000 export const ABI_RETURN_VALUE_LOG_PREFIX = Bytes.fromHex('151F7C75') + +export const UINT64_OVERFLOW_UNDERFLOW_MESSAGE = 'Uint64 overflow or underflow' +export const BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE = 'BigUint overflow or underflow' diff --git a/src/context-helpers/internal-context.ts b/src/context-helpers/internal-context.ts index 8a2c8e6..0a27c2c 100644 --- a/src/context-helpers/internal-context.ts +++ b/src/context-helpers/internal-context.ts @@ -1,4 +1,4 @@ -import { internal } from '@algorandfoundation/algorand-typescript' +import { Account, internal } from '@algorandfoundation/algorand-typescript' import { AccountData } from '../impl/account' import { ApplicationData } from '../impl/application' import { AssetData } from '../impl/asset' @@ -43,9 +43,8 @@ class InternalContext { return this.value.txn.activeGroup } - getAccountData(accountPublicKey: internal.primitives.StubBytesCompat): AccountData { - const key = internal.primitives.BytesCls.fromCompat(accountPublicKey) - const data = this.ledger.accountDataMap.get(key.toString()) + 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') } diff --git a/src/impl/account.ts b/src/impl/account.ts index 78dc416..f803125 100644 --- a/src/impl/account.ts +++ b/src/impl/account.ts @@ -2,9 +2,10 @@ import { Account, Application, Asset, bytes, internal, uint64 } from '@algorandf import { DEFAULT_ACCOUNT_MIN_BALANCE, ZERO_ADDRESS } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { Mutable } from '../typescript-helpers' -import { asBytes, asUint64, asUint64Cls } from '../util' +import { asUint64, asUint64Cls } from '../util' import { ApplicationCls } from './application' import { AssetCls } from './asset' +import { BytesBackedCls } from './base' export class AssetHolding { balance: uint64 @@ -38,15 +39,17 @@ export class AccountData { } } -export class AccountCls implements Account { - readonly bytes: bytes - - constructor(address?: internal.primitives.StubBytesCompat) { - this.bytes = asBytes(address ?? ZERO_ADDRESS) +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.bytes) + return lazyContext.getAccountData(this) } get balance(): uint64 { diff --git a/src/impl/application.ts b/src/impl/application.ts index 2d17daa..b77ab45 100644 --- a/src/impl/application.ts +++ b/src/impl/application.ts @@ -4,6 +4,7 @@ import { ALWAYS_APPROVE_TEAL_PROGRAM } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { Mutable } from '../typescript-helpers' import { asBigInt, asUint64 } from '../util' +import { Uint64BackedCls } from './base' export class ApplicationData { application: Mutable> & { appLogs: bytes[] } @@ -28,11 +29,13 @@ export class ApplicationData { } } -export class ApplicationCls implements Application { - readonly id: uint64 +export class ApplicationCls extends Uint64BackedCls implements Application { + get id() { + return this.uint64 + } constructor(id?: uint64) { - this.id = asUint64(id ?? 0) + super(asUint64(id ?? 0)) } private get data(): ApplicationData { @@ -64,6 +67,6 @@ export class ApplicationCls implements Application { } get address(): Account { const addr = algosdk.getApplicationAddress(asBigInt(this.id)) - return Account(Bytes(addr)) + return Account(Bytes.fromBase32(addr)) } } diff --git a/src/impl/asset-holding.ts b/src/impl/asset-holding.ts index d028e16..b25bb9b 100644 --- a/src/impl/asset-holding.ts +++ b/src/impl/asset-holding.ts @@ -15,7 +15,7 @@ const getAssetHolding = ( return undefined } - const accountData = lazyContext.getAccountData(account.bytes) + const accountData = lazyContext.getAccountData(account) const holding = accountData.optedAssets.get(asBigInt(asset.id)) if (holding === undefined) { return undefined diff --git a/src/impl/asset.ts b/src/impl/asset.ts index 3ac36b7..bc34ace 100644 --- a/src/impl/asset.ts +++ b/src/impl/asset.ts @@ -1,16 +1,19 @@ import { Account, Asset, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { asBigInt, asUint64 } from '../util' import { Mutable } from '../typescript-helpers' +import { asBigInt, asUint64 } from '../util' import { AssetHolding } from './account' +import { Uint64BackedCls } from './base' export type AssetData = Mutable> -export class AssetCls implements Asset { - readonly id: uint64 +export class AssetCls extends Uint64BackedCls implements Asset { + get id(): uint64 { + return this.uint64 + } constructor(id?: internal.primitives.StubUint64Compat) { - this.id = asUint64(id ?? 0) + super(asUint64(id ?? 0)) } private get data(): AssetData { @@ -61,7 +64,7 @@ export class AssetCls implements Asset { } private getAssetHolding(account: Account): AssetHolding { - const accountData = lazyContext.getAccountData(account.bytes) + const accountData = lazyContext.getAccountData(account) if (!accountData.optedAssets.has(asBigInt(this.id))) { 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.', diff --git a/src/impl/base.ts b/src/impl/base.ts new file mode 100644 index 0000000..15f5f94 --- /dev/null +++ b/src/impl/base.ts @@ -0,0 +1,24 @@ +import { bytes, uint64 } from '@algorandfoundation/algorand-typescript' + +export abstract class BytesBackedCls { + #value: bytes + + get bytes() { + return this.#value + } + constructor(value: bytes) { + this.#value = value + } +} + +export abstract class Uint64BackedCls { + #value: uint64 + + get uint64() { + return this.#value + } + + constructor(value: uint64) { + this.#value = value + } +} diff --git a/src/impl/crypto.ts b/src/impl/crypto.ts index 093d0e5..be9ef02 100644 --- a/src/impl/crypto.ts +++ b/src/impl/crypto.ts @@ -1,14 +1,14 @@ -import { Bytes, bytes, internal, gtxn, arc4 } from '@algorandfoundation/algorand-typescript' +import { arc4, bytes, Bytes, gtxn, internal } from '@algorandfoundation/algorand-typescript' +import algosdk from 'algosdk' 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 nacl from 'tweetnacl' -import { notImplementedError } from '../errors' +import { LOGIC_DATA_PREFIX } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import algosdk from 'algosdk' +import { notImplementedError } from '../errors' import { asBytes, asBytesCls } from '../util' -import { LOGIC_DATA_PREFIX } from '../constants' export const sha256 = (a: internal.primitives.StubBytesCompat): bytes => { const bytesA = internal.primitives.BytesCls.fromCompat(a) @@ -62,7 +62,7 @@ export const ed25519verify = ( const logicSig = new algosdk.LogicSig(programBytes.asUint8Array()) const decodedAddress = algosdk.decodeAddress(logicSig.address()) - const addressBytes = asBytes(decodedAddress.publicKey) + const addressBytes = Bytes(decodedAddress.publicKey) const data = LOGIC_DATA_PREFIX.concat(addressBytes).concat(asBytes(a)) return ed25519verifyBare(data, b, c) } @@ -114,7 +114,7 @@ export const ecdsaPkRecover = ( const x = pubKey.getX().toArray('be') const y = pubKey.getY().toArray('be') - return [Bytes(new Uint8Array(x)), Bytes(new Uint8Array(y))] + return [Bytes(x), Bytes(y)] } export const ecdsaPkDecompress = (v: internal.opTypes.Ecdsa, a: internal.primitives.StubBytesCompat): readonly [bytes, bytes] => { diff --git a/src/impl/global.ts b/src/impl/global.ts index 8616266..41ed7a5 100644 --- a/src/impl/global.ts +++ b/src/impl/global.ts @@ -1,5 +1,5 @@ import { Account, Application, Bytes, bytes, internal, op, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' -import { lazyContext } from '../context-helpers/internal-context' +import algosdk from 'algosdk' import { DEFAULT_ACCOUNT_MIN_BALANCE, DEFAULT_ASSET_CREATE_MIN_BALANCE, @@ -9,8 +9,8 @@ import { MIN_TXN_FEE, ZERO_ADDRESS, } from '../constants' +import { lazyContext } from '../context-helpers/internal-context' import { asBigInt, getObjectReference } from '../util' -import algosdk from 'algosdk' export class GlobalData { minTxnFee: uint64 @@ -129,7 +129,7 @@ export const Global: internal.opTypes.GlobalType = { */ get currentApplicationAddress(): Account { const appAddress = algosdk.getApplicationAddress(asBigInt(this.currentApplicationId.id)) - return Account(Bytes(appAddress)) + return Account(Bytes.fromBase32(appAddress)) }, /** @@ -164,7 +164,7 @@ export const Global: internal.opTypes.GlobalType = { */ get callerApplicationAddress(): Account { const appAddress = algosdk.getApplicationAddress(asBigInt(this.callerApplicationId)) - return Account(Bytes(appAddress)) + return Account(Bytes.fromBase32(appAddress)) }, /** diff --git a/src/impl/pure.ts b/src/impl/pure.ts index a37442c..1dd7d7f 100644 --- a/src/impl/pure.ts +++ b/src/impl/pure.ts @@ -1,6 +1,6 @@ import { biguint, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT64, MAX_UINT8, UINT64_SIZE } from '../constants' -import { notImplementedError } from '../errors' +import { notImplementedError, testInvariant } from '../errors' import { asBigUint, asBytes, asMaybeBytesCls, asMaybeUint64Cls, asUint64Cls, binaryStringToBytes } from '../util' export const addw = (a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): readonly [uint64, uint64] => { @@ -21,7 +21,7 @@ export const base64Decode = (e: internal.opTypes.Base64, a: internal.primitives. } const uint8ArrayResult = new Uint8Array(bufferResult) - return asBytes(uint8ArrayResult) + return Bytes(uint8ArrayResult) } export const bitLength = (a: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat): uint64 => { @@ -150,7 +150,7 @@ export const getBit = ( a: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat, ): uint64 => { - const binaryString = toBinaryString(a) + const binaryString = toBinaryString(internal.primitives.isUint64(a) ? asUint64Cls(a).toBytes().asAlgoTs() : asBytes(a)) const index = internal.primitives.Uint64Cls.fromCompat(b).asNumber() const adjustedIndex = asMaybeUint64Cls(a) ? binaryString.length - index - 1 : index if (adjustedIndex < 0 || adjustedIndex >= binaryString.length) { @@ -238,16 +238,20 @@ export const setBit = (( c: internal.primitives.StubUint64Compat, ) => { const uint64Cls = asMaybeUint64Cls(a) - const bytesCls = asMaybeBytesCls(a) - const binaryString = toBinaryString((uint64Cls ?? bytesCls)!) - - const isUint64 = !!uint64Cls - const indexFromLeft = internal.primitives.Uint64Cls.fromCompat(b).asNumber() - const indexFromRight = binaryString.length - indexFromLeft - 1 + const indexParam = internal.primitives.Uint64Cls.fromCompat(b).asNumber() const bit = internal.primitives.Uint64Cls.fromCompat(c).asNumber() - - const newBytes = doSetBit(binaryString, isUint64 ? indexFromRight : indexFromLeft, bit) - return isUint64 ? newBytes.toUint64().asAlgoTs() : newBytes.asAlgoTs() + if (uint64Cls) { + const binaryString = toBinaryString(uint64Cls?.toBytes().asAlgoTs()) + const index = binaryString.length - indexParam - 1 + const newBytes = doSetBit(binaryString, index, bit) + return newBytes.toUint64().asAlgoTs() + } else { + const bytesCls = asMaybeBytesCls(a) + testInvariant(bytesCls, 'a must be uint64 or bytes') + const binaryString = toBinaryString(bytesCls.asAlgoTs()) + const newBytes = doSetBit(binaryString, indexParam, bit) + return newBytes.asAlgoTs() + } }) as SetBitType export const setByte = ( @@ -255,19 +259,19 @@ export const setByte = ( b: internal.primitives.StubUint64Compat, c: internal.primitives.StubUint64Compat, ): bytes => { - const binaryString = toBinaryString(a) + const binaryString = toBinaryString(internal.primitives.BytesCls.fromCompat(a).asAlgoTs()) const byteIndex = internal.primitives.Uint64Cls.fromCompat(b).asNumber() const bitIndex = byteIndex * BITS_IN_BYTE - const replacementNumber = internal.primitives.Uint64Cls.fromCompat(c).asBigInt() - const replacement = replacementNumber === 0n ? '0'.repeat(BITS_IN_BYTE) : toBinaryString(c, true) + const replacementNumber = internal.primitives.Uint64Cls.fromCompat(c) + const replacement = toBinaryString(replacementNumber.toBytes().at(-1).asAlgoTs()) if (bitIndex >= binaryString.length) { internal.errors.codeError(`setByte index ${byteIndex} is beyond length`) } - if (replacementNumber > MAX_UINT8) { - internal.errors.codeError(`setByte value ${replacementNumber} > ${MAX_UINT8}`) + if (replacementNumber.valueOf() > MAX_UINT8) { + internal.errors.codeError(`setByte value ${replacementNumber.asNumber()} > ${MAX_UINT8}`) } const updatedString = binaryString.slice(0, bitIndex) + replacement + binaryString.slice(bitIndex + replacement.length) const updatedBytes = binaryStringToBytes(updatedString) @@ -350,18 +354,8 @@ const uint128ToBigInt = (a: internal.primitives.StubUint64Compat, b: internal.pr return (bigIntA << 64n) + bigIntB } -const toBinaryString = (a: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, isDynamic = false): string => { - const uint64Cls = asMaybeUint64Cls(a) - const bytesCls = asMaybeBytesCls(a) - let binaryString: string = '' - if (uint64Cls) { - binaryString = [...uint64Cls.toBytes(isDynamic).asUint8Array()].map((x) => x.toString(2).padStart(BITS_IN_BYTE, '0')).join('') - } else if (bytesCls) { - binaryString = [...bytesCls.asUint8Array()].map((x) => x.toString(2).padStart(BITS_IN_BYTE, '0')).join('') - } else { - internal.errors.codeError('unknown type for argument a') - } - return binaryString +const toBinaryString = (a: bytes): string => { + return [...internal.primitives.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 => { diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index f02076b..b7f043f 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -25,8 +25,8 @@ type UnaryOps = '~' function tryGetBigInt(value: unknown): bigint | undefined { if (typeof value == 'bigint') return value if (typeof value == 'number') return BigInt(value) - if (value instanceof internal.primitives.Uint64Cls) return value.value - if (value instanceof internal.primitives.BigUintCls) return value.value + if (value instanceof internal.primitives.Uint64Cls) return value.valueOf() + if (value instanceof internal.primitives.BigUintCls) return value.valueOf() return undefined } @@ -66,8 +66,8 @@ export function unaryOp(operand: unknown, op: UnaryOps) { } function uint64BinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps): DeliberateAny { - const lbi = internal.primitives.Uint64Cls.fromCompat(left).value - const rbi = internal.primitives.Uint64Cls.fromCompat(right).value + const lbi = internal.primitives.Uint64Cls.fromCompat(left).valueOf() + const rbi = internal.primitives.Uint64Cls.fromCompat(right).valueOf() const result = (function () { switch (op) { case '+': @@ -121,8 +121,8 @@ function uint64BinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps } function bigUintBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps): DeliberateAny { - const lbi = internal.primitives.checkBigUint(internal.primitives.BigUintCls.fromCompat(left).value) - const rbi = internal.primitives.checkBigUint(internal.primitives.BigUintCls.fromCompat(right).value) + const lbi = internal.primitives.checkBigUint(internal.primitives.BigUintCls.fromCompat(left).valueOf()) + const rbi = internal.primitives.checkBigUint(internal.primitives.BigUintCls.fromCompat(right).valueOf()) const result = (function () { switch (op) { case '+': @@ -260,7 +260,7 @@ function defaultBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp } function uint64UnaryOp(operand: DeliberateAny, op: UnaryOps): DeliberateAny { - const obi = internal.primitives.Uint64Cls.fromCompat(operand).value + const obi = internal.primitives.Uint64Cls.fromCompat(operand).valueOf() switch (op) { case '~': return ~obi & MAX_UINT64 diff --git a/src/set-up.ts b/src/set-up.ts index 1cf8fe9..718bd12 100644 --- a/src/set-up.ts +++ b/src/set-up.ts @@ -1,4 +1,6 @@ import { internal } from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { AccountCls } from './impl/account' type Tester = (this: TesterContext, a: unknown, b: unknown, customTesters: Array) => boolean | undefined interface TesterContext { @@ -26,9 +28,50 @@ function addEqualityTesters(expectObj: ExpectObj) { const testValue = typeof test === 'bigint' ? test : typeof test === 'number' ? BigInt(test) : undefined if (testValue !== undefined) return this.equals(subject.valueOf(), testValue, customTesters) return undefined - } else if (test instanceof internal.primitives.Uint64Cls || test instanceof internal.primitives.BigUintCls) { - const subjectValue = typeof subject === 'bigint' ? subject : typeof subject === 'number' ? BigInt(subject) : undefined - if (subjectValue !== undefined) return this.equals(subjectValue, test.valueOf(), customTesters) + } + // Defer to other testers + return undefined + }, + function BytesPrimitiveIsUint8Array(this: TesterContext, subject, test, customTesters): boolean | undefined { + if (subject instanceof internal.primitives.BytesCls) { + const testValue = test instanceof Uint8Array ? test : undefined + if (testValue !== undefined) return this.equals(subject.asUint8Array(), testValue, customTesters) + return undefined + } + // Defer to other testers + 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 (testValue !== undefined) return this.equals(subject.asUint8Array(), testValue, customTesters) + return undefined + } + // Defer to other testers + return undefined + }, + function BytesPrimitiveIsString(this: TesterContext, subject, test, customTesters): boolean | undefined { + if (subject instanceof internal.primitives.BytesCls) { + const testValue = typeof test === 'string' ? encodingUtil.utf8ToUint8Array(test) : undefined + if (testValue !== undefined) return this.equals(subject.asUint8Array(), testValue, 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 + if (testValue !== undefined) return this.equals(subject.bytes, testValue, customTesters) + return undefined + } + // Defer to other testers + return undefined + }, + 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 + if (testValue !== undefined) return this.equals(subject.bytes, testValue, customTesters) return undefined } // Defer to other testers diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index 5daf650..20f9ce5 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -1,17 +1,18 @@ import { Account, Application, Asset, BaseContract, internal } from '@algorandfoundation/algorand-typescript' +import { AccountMap } 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 { asBigInt, asBytesCls, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' import { GlobalData } from '../impl/global' +import { asBigInt, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' export class LedgerContext { appIdIter = iterBigInt(1001n, MAX_UINT64) assetIdIter = iterBigInt(1001n, MAX_UINT64) applicationDataMap = new Map() appIdContractMap = new Map() - accountDataMap = new Map() + accountDataMap = new AccountMap() assetDataMap = new Map() globalData = new GlobalData() @@ -49,20 +50,19 @@ export class LedgerContext { /** * Update asset holdings for account, only specified values will be updated. * Account will also be opted-in to asset - * @param accountAddress + * @param account * @param assetId * @param balance * @param frozen */ updateAssetHolding( - accountAddress: internal.primitives.StubBytesCompat | Account, + account: Account, assetId: internal.primitives.StubUint64Compat | Asset, balance?: internal.primitives.StubUint64Compat, frozen?: boolean, ): void { - const addr = (asMaybeBytesCls(accountAddress) ?? asBytesCls((accountAddress as Account).bytes)).toString() const id = (asMaybeUint64Cls(assetId) ?? asUint64Cls((assetId as Asset).id)).asBigInt() - const accountData = this.accountDataMap.get(addr)! + const accountData = this.accountDataMap.get(account)! const asset = this.assetDataMap.get(id)! const holding = accountData.optedAssets.get(id) ?? new AssetHolding(0n, asset.defaultFrozen) if (balance !== undefined) holding.balance = asUint64(balance) diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 26a67f2..9653a53 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -6,19 +6,19 @@ import * as ops from './impl' import { AccountCls } from './impl/account' import { ApplicationCls } from './impl/application' import { AssetCls } from './impl/asset' -import { ContractContext } from './subcontexts/contract-context' -import { LedgerContext } from './subcontexts/ledger-context' -import { TransactionContext } from './subcontexts/transaction-context' -import { ValueGenerator } from './value-generators' import { - submitGroup as itxnSubmitGroup, - payment as itxnPayment, - keyRegistration as itxnKeyRegistration, + applicationCall as itxnApplicationCall, assetConfig as itxnAssetConfig, - assetTransfer as itxnAssetTransfer, assetFreeze as itxnAssetFreeze, - applicationCall as itxnApplicationCall, + assetTransfer as itxnAssetTransfer, + keyRegistration as itxnKeyRegistration, + payment as itxnPayment, + submitGroup as itxnSubmitGroup, } from './impl/inner-transactions' +import { ContractContext } from './subcontexts/contract-context' +import { LedgerContext } from './subcontexts/ledger-context' +import { TransactionContext } from './subcontexts/transaction-context' +import { ValueGenerator } from './value-generators' export class TestExecutionContext implements internal.ExecutionContext { #applicationLogs: Map @@ -35,7 +35,7 @@ export class TestExecutionContext implements internal.ExecutionContext { this.#ledgerContext = new LedgerContext() this.#txnContext = new TransactionContext() this.#valueGenerator = new ValueGenerator() - this.#defaultSender = Account(Bytes(algosdk.generateAccount().addr)) + this.#defaultSender = Account(Bytes.fromBase32(algosdk.generateAccount().addr)) } account(address?: bytes): Account { diff --git a/src/util.ts b/src/util.ts index c298be2..8c5835d 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,6 +1,7 @@ -import { internal, bytes } from '@algorandfoundation/algorand-typescript' +import { Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' import { randomBytes } from 'crypto' import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT8, UINT512_SIZE } from './constants' +import { BytesBackedCls, Uint64BackedCls } from './impl/base' import { DeliberateAny } from './typescript-helpers' export const nameOfType = (x: unknown) => { @@ -54,7 +55,23 @@ export const toBytes = (val: unknown): bytes => { } const bytesVal = asMaybeBytesCls(val) if (bytesVal !== undefined) { - return bytesVal.toBytes().asAlgoTs() + return bytesVal.asAlgoTs() + } + if (val instanceof BytesBackedCls) { + return val.bytes + } + if (val instanceof Uint64BackedCls) { + return asUint64Cls(val.uint64).toBytes().asAlgoTs() + } + if (Array.isArray(val)) { + // This hack handles tuples/arrays of uint64 only + return val.reduce((acc: bytes, cur: unknown) => { + const uint64Val = asMaybeUint64Cls(cur) + if (!uint64Val) { + internal.errors.internalError(`ABI tuple encoding not supported: ${nameOfType(val)}`) + } + return acc.concat(toBytes(cur)) + }, Bytes()) } internal.errors.internalError(`Invalid type for bytes: ${nameOfType(val)}`) } @@ -113,7 +130,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(new Uint8Array(randomBytes(length))) +export const getRandomBytes = (length: number): internal.primitives.BytesCls => asBytesCls(Bytes(randomBytes(length))) const NoValue = Symbol('no-value') type LazyInstance = () => T diff --git a/src/value-generators/avm.ts b/src/value-generators/avm.ts index 810db87..d7ab239 100644 --- a/src/value-generators/avm.ts +++ b/src/value-generators/avm.ts @@ -3,13 +3,13 @@ import algosdk from 'algosdk' import { randomBytes } from 'crypto' import { MAX_BYTES_SIZE, MAX_UINT64, ZERO_ADDRESS } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { AccountCls, AccountData } from '../impl/account' +import { AccountData } from '../impl/account' import { ApplicationCls, ApplicationData } from '../impl/application' import { AssetCls, AssetData } from '../impl/asset' -import { asBigInt, asBytesCls, asUint64Cls, getRandomBigInt } from '../util' +import { asBigInt, asUint64Cls, getRandomBigInt } from '../util' type AccountContextData = Partial & { - address?: internal.primitives.StubBytesCompat + address?: Account optedAssetBalances?: Map optedApplications?: Application[] } @@ -37,25 +37,25 @@ export class AvmValueGenerator { } account(input?: AccountContextData): Account { - const addr = input?.address ? asBytesCls(input.address).toString() : undefined - if (addr && lazyContext.ledger.accountDataMap.has(addr)) { + const account = input?.address ?? Account(Bytes.fromBase32(algosdk.generateAccount().addr)) + + if (input?.address && lazyContext.ledger.accountDataMap.has(account)) { internal.errors.internalError( 'Account with such address already exists in testing context. Use `context.ledger.getAccount(address)` to retrieve the existing account.', ) } - const accountAddress = addr ?? algosdk.generateAccount().addr const data = new AccountData() - const { address, optedAssetBalances, optedApplications, ...account } = input ?? {} + const { address, optedAssetBalances, optedApplications, ...accountData } = input ?? {} data.account = { ...data.account, - ...account, + ...accountData, } - lazyContext.ledger.accountDataMap.set(accountAddress, data) + lazyContext.ledger.accountDataMap.set(account, data) if (input?.optedAssetBalances) { for (const [assetId, balance] of input.optedAssetBalances) { - lazyContext.ledger.updateAssetHolding(accountAddress, assetId, balance) + lazyContext.ledger.updateAssetHolding(account, assetId, balance) } } if (input?.optedApplications) { @@ -63,7 +63,7 @@ export class AvmValueGenerator { data.optedApplications.set(asBigInt(app.id), app) } } - return new AccountCls(Bytes(accountAddress)) + return account } asset(input?: AssetContextData): Asset { diff --git a/tests/avm-invoker.ts b/tests/avm-invoker.ts index f2e07d6..3274f4f 100644 --- a/tests/avm-invoker.ts +++ b/tests/avm-invoker.ts @@ -1,4 +1,3 @@ -import { internal, uint64 } from '@algorandfoundation/algorand-typescript' import * as algokit from '@algorandfoundation/algokit-utils' import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import { ABIAppCallArg, ABIReturn } from '@algorandfoundation/algokit-utils/types/app' @@ -7,7 +6,8 @@ import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { KmdAccountManager } from '@algorandfoundation/algokit-utils/types/kmd-account-manager' import { nullLogger } from '@algorandfoundation/algokit-utils/types/logging' import { SendTransactionFrom, SendTransactionParams } from '@algorandfoundation/algokit-utils/types/transaction' -import { ABIValue, Account as algoSdkAccount, generateAccount } from 'algosdk' +import { Account, Bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { ABIValue, generateAccount } from 'algosdk' import { randomUUID } from 'crypto' import { asUint64, getRandomNumber, Lazy } from '../src/util' @@ -30,7 +30,7 @@ export const getAlgorandAppClientWithApp = async (appSpec: AppSpec) => { return [appClient, app] as const } -const inovkeMethod = async ( +const invokeMethod = async ( appClient: ApplicationClient, method: string, sendParams?: SendTransactionParams, @@ -51,7 +51,7 @@ export const getAvmResult = async ( method: string, ...methodArgs: ABIAppCallArg[] ): Promise => { - const result = await inovkeMethod(appClient, method, sendParams, ...methodArgs) + const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) return result.returnValue as TResult } @@ -60,8 +60,8 @@ export const getAvmResultRaw = async ( method: string, ...methodArgs: ABIAppCallArg[] ): Promise => { - const result = await inovkeMethod(appClient, method, sendParams, ...methodArgs) - return result.rawReturnValue?.slice(ARC4_PREFIX_LENGTH) + const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) + return result.rawReturnValue } export const getLocalNetDefaultAccount = () => { @@ -70,7 +70,7 @@ export const getLocalNetDefaultAccount = () => { return kmdAccountManager.getLocalNetDispenserAccount() } -export const generateTestAccount = async (): Promise => { +export const generateTestAccount = async (): Promise => { const account = generateAccount() await algokit.ensureFunded( @@ -80,7 +80,7 @@ export const generateTestAccount = async (): Promise => { }, algorandClient().client.algod, ) - return account + return Account(Bytes.fromBase32(account.addr)) } export const generateTestAsset = async (fields: { diff --git a/tests/crypto-op-codes.spec.ts b/tests/crypto-op-codes.spec.ts index 50adbed..847152c 100644 --- a/tests/crypto-op-codes.spec.ts +++ b/tests/crypto-op-codes.spec.ts @@ -1,6 +1,6 @@ -import { Bytes, internal, op as publicOps, uint64 } from '@algorandfoundation/algorand-typescript' import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { Bytes, internal, op as publicOps, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' import { ec } from 'elliptic' import { keccak256 as js_keccak256 } from 'js-sha3' @@ -10,8 +10,8 @@ import { TestExecutionContext } from '../src' import { MAX_BYTES_SIZE } from '../src/constants' import * as op from '../src/impl/crypto' import appSpecJson from './artifacts/crypto-ops/data/CryptoOpsContract.arc32.json' -import { getAlgorandAppClientWithApp, getAvmResult, getAvmResultRaw } from './avm-invoker' -import { asUint8Array, getPaddedUint8Array } from './util' +import { getAlgorandAppClientWithApp, getAvmResult } from './avm-invoker' +import { asUint8Array, getPaddedBytes } from './util' const MAX_ARG_LEN = 2048 const curveMap = { @@ -41,10 +41,10 @@ describe('crypto op codes', async () => { ['abc', 0], ['abc', MAX_BYTES_SIZE - 3], ])('should return the correct sha256 hash', async (a, padSize) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_sha256', asUint8Array(a), padSize))! - const paddedA = getPaddedUint8Array(padSize, a) + const avmResult = (await getAvmResult({ appClient }, 'verify_sha256', asUint8Array(a), padSize))! + const paddedA = getPaddedBytes(padSize, a) const result = op.sha256(paddedA) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) }) }) @@ -55,10 +55,10 @@ describe('crypto op codes', async () => { ['abc', 0], ['abc', MAX_BYTES_SIZE - 3], ])('should return the correct sha3_256 hash', async (a, padSize) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_sha3_256', asUint8Array(a), padSize))! - const paddedA = getPaddedUint8Array(padSize, a) + const avmResult = (await getAvmResult({ appClient }, 'verify_sha3_256', asUint8Array(a), padSize))! + const paddedA = getPaddedBytes(padSize, a) const result = op.sha3_256(paddedA) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) }) }) @@ -69,10 +69,10 @@ describe('crypto op codes', async () => { ['abc', 0], ['abc', MAX_BYTES_SIZE - 3], ])('should return the correct keccak256 hash', async (a, padSize) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_keccak_256', asUint8Array(a), padSize))! - const paddedA = getPaddedUint8Array(padSize, a) + const avmResult = (await getAvmResult({ appClient }, 'verify_keccak_256', asUint8Array(a), padSize))! + const paddedA = getPaddedBytes(padSize, a) const result = op.keccak256(paddedA) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) expect(result.length.valueOf()).toBe(32n) }) }) @@ -84,10 +84,10 @@ describe('crypto op codes', async () => { ['abc', 0], ['abc', MAX_BYTES_SIZE - 3], ])('should return the correct sha512_256 hash', async (a, padSize) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_sha512_256', asUint8Array(a), padSize))! - const paddedA = getPaddedUint8Array(padSize, a) + const avmResult = (await getAvmResult({ appClient }, 'verify_sha512_256', asUint8Array(a), padSize))! + const paddedA = getPaddedBytes(padSize, a) const result = op.sha512_256(paddedA) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) expect(result.length.valueOf()).toBe(32n) }) }) @@ -105,7 +105,7 @@ describe('crypto op codes', async () => { signature, keyPair.publicKey, ) - const result = op.ed25519verifyBare(message, signature, keyPair.publicKey) + const result = op.ed25519verifyBare(message, Bytes(signature), Bytes(keyPair.publicKey)) expect(result).toEqual(avmResult) }) }) @@ -131,7 +131,7 @@ describe('crypto op codes', async () => { ) ctx.txn.createScope([appCallTxn]).execute(() => { - const result = op.ed25519verify(message, signature, publicKey) + const result = op.ed25519verify(message, Bytes(signature), Bytes(publicKey)) expect(result).toEqual(avmResult) }) }) @@ -200,8 +200,8 @@ describe('crypto op codes', async () => { ) const result = op.ecdsaPkRecover(internal.opTypes.Ecdsa.Secp256k1, a, b, c, d) - expect(asUint8Array(result[0])).toEqual(new Uint8Array(avmResult[0])) - expect(asUint8Array(result[1])).toEqual(new Uint8Array(avmResult[1])) + 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 () => { @@ -237,7 +237,7 @@ describe('crypto op codes', async () => { 'verify_ecdsa_decompress_k1', pubKeyArray, ) - const result = op.ecdsaPkDecompress(v, pubKeyArray) + const result = op.ecdsaPkDecompress(v, Bytes(pubKeyArray)) expect(asUint8Array(result[0])).toEqual(new Uint8Array(avmResult[0])) expect(asUint8Array(result[1])).toEqual(new Uint8Array(avmResult[1])) diff --git a/tests/primitives/biguint.spec.ts b/tests/primitives/biguint.spec.ts index b21694f..4b3833a 100644 --- a/tests/primitives/biguint.spec.ts +++ b/tests/primitives/biguint.spec.ts @@ -1,10 +1,13 @@ +// 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 type { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { describe, expect, it } from 'vitest' +import { BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE, MAX_UINT512, MAX_UINT64 } from '../../src/constants' import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' -import { MAX_UINT512, MAX_UINT64 } from '../../src/constants' +import { abiAsBytes } from '../util' const asBigUint = (val: bigint | number) => (typeof val === 'bigint' ? BigUint(val) : BigUint(val)) @@ -146,74 +149,66 @@ describe('BigUint', async () => { await expect(getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, bytesB)).rejects.toThrow( 'math attempted on large byte-array', ) - expect(() => getStubResult(bigUintA, bigUintB)).toThrow('BigUint over or underflow') + expect(() => getStubResult(bigUintA, bigUintB)).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) - expect(() => getStubResult(a, bigUintB)).toThrow('BigUint over or underflow') + expect(() => getStubResult(a, bigUintB)).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) - expect(() => getStubResult(bigUintA, b)).toThrow('BigUint over or underflow') + expect(() => getStubResult(bigUintA, b)).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) }) }) }) describe.each([ - [0, 0], - [0, MAX_UINT512], - [MAX_UINT512, 0], - [1, 0], - [0, 1], - [1, 1], + [0n, 0n], + [0n, MAX_UINT512], + [MAX_UINT512, 0n], + [1n, 0n], + [0n, 1n], + [1n, 1n], [MAX_UINT64, MAX_UINT64], - [1, MAX_UINT512 - 1n], - [MAX_UINT512 - 1n, 1], + [1n, MAX_UINT512 - 1n], + [MAX_UINT512 - 1n, 1n], ])('addition', async (a, b) => { it(`${a} + ${b}`, async () => { - const bigUintA = asBigUint(a) - const bigUintB = asBigUint(b) + const bigUintA = BigUint(a) + const bigUintB = BigUint(b) const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_add', bytesA, bytesB))! - const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_add', bytesA, bytesB))) + let result = bigUintA + bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) - if (typeof a === 'bigint') { - result = a + bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) - } + result = a + bigUintB + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) - if (typeof b === 'bigint') { - result = bigUintA + b - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) - } + result = bigUintA + b + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) }) }) describe.each([ - [MAX_UINT512, 1], - [1, MAX_UINT512], + [MAX_UINT512, 1n], + [1n, MAX_UINT512], [MAX_UINT512, MAX_UINT512], ])('addition result overflow', async (a, b) => { it(`${a} + ${b}`, async () => { - const bigUintA = asBigUint(a) - const bigUintB = asBigUint(b) + const bigUintA = BigUint(a) + const bigUintB = BigUint(b) const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_add', bytesA, bytesB))! - const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_add', bytesA, bytesB))) + let result = bigUintA + bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) - if (typeof a === 'bigint') { - result = a + bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) - } + result = a + bigUintB + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) - if (typeof b === 'bigint') { - result = bigUintA + b - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) - } + result = bigUintA + b + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) }) }) @@ -231,56 +226,52 @@ describe('BigUint', async () => { await expect(getAvmResultRaw({ appClient }, 'verify_biguint_add', bytesA, bytesB)).rejects.toThrow( 'math attempted on large byte-array', ) - expect(() => bigUintA + bigUintB).toThrow('BigUint over or underflow') + expect(() => bigUintA + bigUintB).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) if (typeof a === 'bigint') { - expect(() => a + bigUintB).toThrow('BigUint over or underflow') + expect(() => a + bigUintB).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) } if (typeof b === 'bigint') { - expect(() => bigUintA + b).toThrow('BigUint over or underflow') + expect(() => bigUintA + b).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) } }) }) describe.each([ - [0, 0], - [1, 0], - [1, 1], + [0n, 0n], + [1n, 0n], + [1n, 1n], [MAX_UINT64, MAX_UINT64], - [MAX_UINT512, 0], - [MAX_UINT512, 1], + [MAX_UINT512, 0n], + [MAX_UINT512, 1n], [MAX_UINT512, MAX_UINT512], ])('subtraction', async (a, b) => { it(`${a} - ${b}`, async () => { - const bigUintA = asBigUint(a) - const bigUintB = asBigUint(b) + const bigUintA = BigUint(a) + const bigUintB = BigUint(b) const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_sub', bytesA, bytesB))! - const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_sub', bytesA, bytesB))) + let result = bigUintA - bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) - if (typeof a === 'bigint') { - result = a - bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) - } + result = a - bigUintB + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) - if (typeof b === 'bigint') { - result = bigUintA - b - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) - } + result = bigUintA - b + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) }) }) describe.each([ - [0, 1], - [1, 2], + [0n, 1n], + [1n, 2n], [MAX_UINT64, MAX_UINT512], - [0, MAX_UINT512], - [1, MAX_UINT512], + [0n, MAX_UINT512], + [1n, MAX_UINT512], ])(`subtraction result underflow`, async (a, b) => { it(`${a} - ${b}`, async () => { const bigUintA = asBigUint(a) @@ -291,23 +282,19 @@ describe('BigUint', async () => { await expect(getAvmResultRaw({ appClient }, 'verify_biguint_sub', bytesA, bytesB)).rejects.toThrow('math would have negative result') expect(() => bigUintA - bigUintB).toThrow('BigUint underflow') - if (typeof a === 'bigint') { - expect(() => a - bigUintB).toThrow('BigUint underflow') - } + expect(() => a - bigUintB).toThrow('BigUint underflow') - if (typeof b === 'bigint') { - expect(() => bigUintA - b).toThrow('BigUint underflow') - } + expect(() => bigUintA - b).toThrow('BigUint underflow') }) }) describe.each([ - [MAX_UINT512 + 1n, 1], - [1, MAX_UINT512 + 1n], + [MAX_UINT512 + 1n, 1n], + [1n, MAX_UINT512 + 1n], [MAX_UINT512 + 1n, MAX_UINT512 + 1n], ])(`subtraction with overflowing input`, async (a, b) => { - const bytesA = internal.encodingUtil.bigIntToUint8Array(BigInt(a)) - const bytesB = internal.encodingUtil.bigIntToUint8Array(BigInt(b)) + const bytesA = internal.encodingUtil.bigIntToUint8Array(a) + const bytesB = internal.encodingUtil.bigIntToUint8Array(b) const bigUintA = BigUint(Bytes(bytesA)) const bigUintB = BigUint(Bytes(bytesB)) @@ -315,15 +302,11 @@ describe('BigUint', async () => { await expect(getAvmResultRaw({ appClient }, 'verify_biguint_sub', bytesA, bytesB)).rejects.toThrow( 'math attempted on large byte-array', ) - expect(() => bigUintA - bigUintB).toThrow('BigUint over or underflow') + expect(() => bigUintA - bigUintB).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) - if (typeof a === 'bigint') { - expect(() => a - bigUintB).toThrow('BigUint over or underflow') - } + expect(() => a - bigUintB).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) - if (typeof b === 'bigint') { - expect(() => bigUintA - b).toThrow('BigUint over or underflow') - } + expect(() => bigUintA - b).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) }) }) @@ -341,19 +324,19 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_mul', bytesA, bytesB))! - const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_mul', bytesA, bytesB))) + let result = bigUintA * bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) if (typeof a === 'bigint') { result = a * bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) } if (typeof b === 'bigint') { result = bigUintA * b - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) } }) }) @@ -369,19 +352,19 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_mul', bytesA, bytesB))! - const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_mul', bytesA, bytesB))) + let result = bigUintA * bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) if (typeof a === 'bigint') { result = a * bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) } if (typeof b === 'bigint') { result = bigUintA * b - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) } }) }) @@ -400,14 +383,14 @@ describe('BigUint', async () => { await expect(getAvmResultRaw({ appClient }, 'verify_biguint_mul', bytesA, bytesB)).rejects.toThrow( 'math attempted on large byte-array', ) - expect(() => bigUintA * bigUintB).toThrow('BigUint over or underflow') + expect(() => bigUintA * bigUintB).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) if (typeof a === 'bigint') { - expect(() => a * bigUintB).toThrow('BigUint over or underflow') + expect(() => a * bigUintB).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) } if (typeof b === 'bigint') { - expect(() => bigUintA * b).toThrow('BigUint over or underflow') + expect(() => bigUintA * b).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) } }) }) @@ -426,19 +409,19 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_div', bytesA, bytesB))! - const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_div', bytesA, bytesB))) + let result = bigUintA / bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) if (typeof a === 'bigint') { result = a / bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) } if (typeof b === 'bigint') { result = bigUintA / b - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) } }) }) @@ -474,14 +457,14 @@ describe('BigUint', async () => { await expect(getAvmResultRaw({ appClient }, 'verify_biguint_div', bytesA, bytesB)).rejects.toThrow( 'math attempted on large byte-array', ) - expect(() => bigUintA / bigUintB).toThrow('BigUint over or underflow') + expect(() => bigUintA / bigUintB).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) if (typeof a === 'bigint') { - expect(() => a / bigUintB).toThrow('BigUint over or underflow') + expect(() => a / bigUintB).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) } if (typeof b === 'bigint') { - expect(() => bigUintA / b).toThrow('BigUint over or underflow') + expect(() => bigUintA / b).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) } }) }) @@ -500,19 +483,18 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_biguint_mod', bytesA, bytesB))! - const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_mod', bytesA, bytesB))) let result = bigUintA % bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) if (typeof a === 'bigint') { result = a % bigUintB - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) } if (typeof b === 'bigint') { result = bigUintA % b - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) } }) }) @@ -548,14 +530,14 @@ describe('BigUint', async () => { await expect(getAvmResultRaw({ appClient }, 'verify_biguint_mod', bytesA, bytesB)).rejects.toThrow( 'math attempted on large byte-array', ) - expect(() => bigUintA % bigUintB).toThrow('BigUint over or underflow') + expect(() => bigUintA % bigUintB).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) if (typeof a === 'bigint') { - expect(() => a % bigUintB).toThrow('BigUint over or underflow') + expect(() => a % bigUintB).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) } if (typeof b === 'bigint') { - expect(() => bigUintA % b).toThrow('BigUint over or underflow') + expect(() => bigUintA % b).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) } }) }) @@ -599,19 +581,18 @@ describe('BigUint', async () => { const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) it(`${a} ${operator} ${b}`, async () => { - const avmResult = (await getAvmResultRaw({ appClient }, `verify_biguint_${op}`, bytesA, bytesB))! - const avmResultValue = internal.encodingUtil.uint8ArrayToBigInt(avmResult) + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, bytesB))) let result = getStubResult(bigUintA, bigUintB) - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) if (typeof a === 'bigint') { result = getStubResult(a, bigUintB) - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) } if (typeof b === 'bigint') { result = getStubResult(bigUintA, b) - expect(result.valueOf(), `for values: ${a}, ${b}`).toBe(avmResultValue) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) } }) }) @@ -620,14 +601,14 @@ describe('BigUint', async () => { describe.each([MAX_UINT512 + 1n, MAX_UINT512 * 2n])('value too big', (a) => { it(`${a}`, () => { const bigUintA = asBigUint(a) - expect(() => bigUintA === a).toThrow('BigUint over or underflow') + expect(() => bigUintA === a).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe.each([-1, -MAX_UINT512, -MAX_UINT512 * 2n])('value too small', (a) => { it(`${a}`, () => { const bigUintA = asBigUint(a) - expect(() => bigUintA === asBigUint(a)).toThrow('BigUint over or underflow') + expect(() => bigUintA === asBigUint(a)).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) }) }) @@ -646,7 +627,7 @@ describe('BigUint', async () => { ])('fromCompat', async (a, b) => { it(`${a}`, async () => { const result = internal.primitives.BigUintCls.fromCompat(a) - expect(result.valueOf(), `for value: ${a}`).toBe(b) + expect(result, `for value: ${a}`).toEqual(b) }) }) }) diff --git a/tests/primitives/bytes.spec.ts b/tests/primitives/bytes.spec.ts index 9377b1c..74321d5 100644 --- a/tests/primitives/bytes.spec.ts +++ b/tests/primitives/bytes.spec.ts @@ -1,10 +1,11 @@ -import { bytes, Bytes, internal } from '@algorandfoundation/algorand-typescript' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { bytes, Bytes, internal } from '@algorandfoundation/algorand-typescript' import { describe, expect, it } from 'vitest' +import { MAX_BYTES_SIZE } from '../../src/constants' +import { sha256 } from '../../src/impl' import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' import { asUint8Array, getSha256Hash, padUint8Array } from '../util' -import { MAX_BYTES_SIZE } from '../../src/constants' describe('Bytes', async () => { const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) @@ -22,13 +23,12 @@ describe('Bytes', async () => { it(`${a} concat ${b}`, async () => { const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) const uint8ArrayB = internal.encodingUtil.utf8ToUint8Array(b) - const avmResult = (await getAvmResultRaw({ appClient }, `verify_bytes_add`, uint8ArrayA, uint8ArrayB, padASize, padBSize))! + const avmResult = (await getAvmResult({ appClient }, `verify_bytes_add`, uint8ArrayA, uint8ArrayB, padASize, padBSize))! const bytesA = Bytes(padUint8Array(uint8ArrayA, padASize)) const bytesB = Bytes(padUint8Array(uint8ArrayB, padBSize)) const result = bytesA.concat(bytesB) - const resultUint8Array = asUint8Array(result) - const resultHash = getSha256Hash(resultUint8Array) + const resultHash = Bytes(getSha256Hash(asUint8Array(result))) expect(resultHash, `for values: ${a}, ${b}`).toEqual(avmResult) }) }) @@ -79,10 +79,9 @@ describe('Bytes', async () => { const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) const uint8ArrayB = internal.encodingUtil.utf8ToUint8Array(b) - const avmResult = (await getAvmResultRaw({ appClient }, `verify_bytes_${op}`, uint8ArrayA, uint8ArrayB))! + const avmResult = (await getAvmResult({ appClient }, `verify_bytes_${op}`, uint8ArrayA, uint8ArrayB))! const result = getStubResult(bytesA, bytesB) - const resultUint8Array = asUint8Array(result) - expect(resultUint8Array, `for values: ${a}, ${b}`).toEqual(avmResult) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) }) }) }) @@ -96,12 +95,11 @@ describe('Bytes', async () => { ])('bitwise invert', async (a, padSize) => { it(`~${a}`, async () => { const uint8ArrayA = internal.encodingUtil.utf8ToUint8Array(a) - const avmResult = (await getAvmResultRaw({ appClient }, `verify_bytes_not`, uint8ArrayA, padSize))! + const avmResult = (await getAvmResult({ appClient }, `verify_bytes_not`, uint8ArrayA, padSize))! const bytesA = Bytes(padUint8Array(uint8ArrayA, padSize)) const result = bytesA.bitwiseInvert() - const resultUint8Array = asUint8Array(result) - const resultHash = getSha256Hash(resultUint8Array) + const resultHash = sha256(result) expect(resultHash, `for value: ${a}`).toEqual(avmResult) }) diff --git a/tests/primitives/uint64.spec.ts b/tests/primitives/uint64.spec.ts index 4c1b490..9d5bc59 100644 --- a/tests/primitives/uint64.spec.ts +++ b/tests/primitives/uint64.spec.ts @@ -1,6 +1,7 @@ -import { internal, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { internal, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { describe, expect, it } from 'vitest' +import { UINT64_OVERFLOW_UNDERFLOW_MESSAGE } from '../../src/constants' import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' @@ -110,14 +111,14 @@ describe('Unit64', async () => { it(`${a} + ${b}`, async () => { await expect(getAvmResult({ appClient }, 'verify_uint64_add', a, b)).rejects.toThrow('+ overflowed') - expect(() => asUint64(a) + asUint64(b)).toThrow('Uint64 over or underflow') + expect(() => asUint64(a) + asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) if (typeof a === 'number') { - expect(() => a + asUint64(b)).toThrow('Uint64 over or underflow') + expect(() => a + asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) } if (typeof b === 'number') { - expect(() => asUint64(a) + b).toThrow('Uint64 over or underflow') + expect(() => asUint64(a) + b).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) } }) }) @@ -158,14 +159,14 @@ describe('Unit64', async () => { it(`${a} - ${b}`, async () => { await expect(getAvmResult({ appClient }, 'verify_uint64_sub', a, b)).rejects.toThrow('- would result negative') - expect(() => asUint64(a) - asUint64(b)).toThrow('Uint64 over or underflow') + expect(() => asUint64(a) - asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) if (typeof a === 'number') { - expect(() => a - asUint64(b)).toThrow('Uint64 over or underflow') + expect(() => a - asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) } if (typeof b === 'number') { - expect(() => asUint64(a) - b).toThrow('Uint64 over or underflow') + expect(() => asUint64(a) - b).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) } }) }) @@ -202,14 +203,14 @@ describe('Unit64', async () => { it(`${a} * ${b}`, async () => { await expect(getAvmResult({ appClient }, 'verify_uint64_mul', a, b)).rejects.toThrow('* overflowed') - expect(() => asUint64(a) * asUint64(b)).toThrow('Uint64 over or underflow') + expect(() => asUint64(a) * asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) if (typeof a === 'number') { - expect(() => a * asUint64(b)).toThrow('Uint64 over or underflow') + expect(() => a * asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) } if (typeof b === 'number') { - expect(() => asUint64(a) * b).toThrow('Uint64 over or underflow') + expect(() => asUint64(a) * b).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) } }) }) @@ -344,14 +345,14 @@ describe('Unit64', async () => { it(`${a} ** ${b}`, async () => { await expect(getAvmResult({ appClient }, 'verify_uint64_pow', a, b)).rejects.toThrow(/\d+\^\d+ overflow/) - expect(() => asUint64(a) ** asUint64(b)).toThrow('Uint64 over or underflow') + expect(() => asUint64(a) ** asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) if (typeof a === 'number') { - expect(() => a ** asUint64(b)).toThrow('Uint64 over or underflow') + expect(() => a ** asUint64(b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) } if (typeof b === 'number') { - expect(() => asUint64(a) ** b).toThrow('Uint64 over or underflow') + expect(() => asUint64(a) ** b).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) } }) }) @@ -472,7 +473,7 @@ describe('Unit64', async () => { expect(() => uintA << uintB).toThrow('expected shift <= 63') expect(() => a << uintB).toThrow('expected shift <= 63') expect(() => uintA << b).toThrow('expected shift <= 63') - expect(() => Uint64(MAX_UINT64 + 1n) << Uint64(1n)).toThrow('Uint64 over or underflow') + expect(() => Uint64(MAX_UINT64 + 1n) << Uint64(1n)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) it('0 >> 64', async () => { @@ -480,19 +481,19 @@ describe('Unit64', async () => { expect(() => uintA >> uintB).toThrow('expected shift <= 63') expect(() => a >> uintB).toThrow('expected shift <= 63') expect(() => uintA >> b).toThrow('expected shift <= 63') - expect(() => Uint64(MAX_UINT64 + 1n) >> Uint64(1n)).toThrow('Uint64 over or underflow') + expect(() => Uint64(MAX_UINT64 + 1n) >> Uint64(1n)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe.each([MAX_UINT64 + 1n, MAX_UINT64 * 2n])('value too big', (a) => { it(`${a}`, () => { - expect(() => Uint64(a)).toThrow('Uint64 over or underflow') + expect(() => Uint64(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe.each([-1, -MAX_UINT64, -MAX_UINT64 * 2n])('value too small', (a) => { it(`${a}`, () => { - expect(() => asUint64(a)).toThrow('Uint64 over or underflow') + expect(() => asUint64(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) diff --git a/tests/pure-op-codes.spec.ts b/tests/pure-op-codes.spec.ts index 2035af9..0085388 100644 --- a/tests/pure-op-codes.spec.ts +++ b/tests/pure-op-codes.spec.ts @@ -1,13 +1,19 @@ -import { BigUint, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { BigUint, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' -import { MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT64 } from '../src/constants' +import { + BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE, + MAX_BYTES_SIZE, + MAX_UINT512, + MAX_UINT64, + UINT64_OVERFLOW_UNDERFLOW_MESSAGE, +} from '../src/constants' import * as op from '../src/impl/pure' -import { asBigUintCls, asBytesCls } from '../src/util' +import { asBigUintCls } from '../src/util' import appSpecJson from './artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from './avm-invoker' -import { asUint8Array, base64Encode, base64UrlEncode, getPaddedUint8Array, getSha256Hash, intToBytes } from './util' +import { abiAsBytes, asUint8Array, base64Encode, base64UrlEncode, getPaddedBytes, getSha256Hash, intToBytes } from './util' const avmIntArgOverflowError = 'is not a non-negative int or too big to fit in size' const extractOutOfBoundError = /extraction (start|end) \d+ is beyond length/ @@ -47,7 +53,7 @@ describe('Pure op codes', async () => { [MAX_UINT512 * 2n, 0], ])('should throw error when input overflows', async (a, b) => { await expect(getAvmResultRaw({ appClient }, 'verify_addw', a, b)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.addw(a, b)).toThrow('Uint64 over or underflow') + expect(() => op.addw(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) @@ -57,15 +63,15 @@ describe('Pure op codes', async () => { base64Encode('abc'), base64Encode('hello, world.'), base64Encode('0123.'), - base64Encode(new Uint8Array([0xff])), - base64Encode(new Uint8Array(Array(256).fill(0x00).concat([0xff]))), + base64Encode(Bytes([0xff])), + base64Encode(Bytes(Array(256).fill(0x00).concat([0xff]))), ])('should decode standard base64 string', async (a) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_base64_decode_standard', asUint8Array(a)))! + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_base64_decode_standard', asUint8Array(a)))! const result = op.base64Decode(internal.opTypes.Base64.StdEncoding, a) - expect(asBytesCls(result).asUint8Array()).toEqual(avmResult) + expect(result).toEqual(avmResult) }) - test.each([Bytes(new Uint8Array(Array(256).fill(0x00).concat([0xff]))), asBigUintCls(BigUint(MAX_UINT512)).toBytes().asAlgoTs()])( + test.each([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) => { await expect(getAvmResultRaw({ appClient }, 'verify_base64_decode_standard', asUint8Array(a))).rejects.toThrow( @@ -80,15 +86,15 @@ describe('Pure op codes', async () => { base64UrlEncode('abc'), base64UrlEncode('hello, world.'), base64UrlEncode('0123.'), - base64UrlEncode(new Uint8Array([0xff])), - base64UrlEncode(new Uint8Array(Array(256).fill(0x00).concat([0xff]))), + base64UrlEncode(Bytes([0xff])), + base64UrlEncode(Bytes(Array(256).fill(0x00).concat([0xff]))), ])('should decode base64url string', async (a) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_base64_decode_url', asUint8Array(a)))! + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_base64_decode_url', asUint8Array(a)))! const result = op.base64Decode(internal.opTypes.Base64.URLEncoding, a) - expect(asBytesCls(result).asUint8Array()).toEqual(avmResult) + expect(result).toEqual(avmResult) }) - test.each([Bytes(new Uint8Array(Array(256).fill(0x00).concat([0xff]))), asBigUintCls(BigUint(MAX_UINT512)).toBytes().asAlgoTs()])( + test.each([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) => { await expect(getAvmResultRaw({ appClient }, 'verify_base64_decode_url', asUint8Array(a))).rejects.toThrow('illegal base64 data') @@ -104,42 +110,42 @@ describe('Pure op codes', async () => { [Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT64)), 0], [Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512)), 0], [Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512 * MAX_UINT512)), 0], - [Bytes(new Uint8Array(Array(8).fill(0x00).concat(Array(4).fill(0x0f)))), 0], - [Bytes(new Uint8Array([0x0f])), MAX_BYTES_SIZE - 1], - [Bytes(new Uint8Array()), 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 = getPaddedUint8Array(padSize, a) + const paddedA = getPaddedBytes(padSize, a) const result = op.bitLength(paddedA) - expect(result.valueOf()).toBe(avmResult) + 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.valueOf()).toBe(avmResult) + 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 over or underflow') + 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 getAvmResultRaw({ appClient }, 'verify_bsqrt', uint8ArrayA))! + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_bsqrt', uint8ArrayA))! const result = op.bsqrt(a) const bytesResult = asBigUintCls(result).toBytes() - expect(bytesResult.asUint8Array()).toEqual(avmResult) + 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 over or underflow') + expect(() => op.bsqrt(a)).toThrow(BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE) }) }) @@ -148,17 +154,17 @@ describe('Pure op codes', async () => { Bytes(internal.encodingUtil.bigIntToUint8Array(0n)), Bytes(internal.encodingUtil.bigIntToUint8Array(1n)), Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT64)), - Bytes(new Uint8Array(Array(4).fill(0x00).concat(Array(4).fill(0x0f)))), + Bytes(Array(4).fill(0x00).concat(Array(4).fill(0x0f))), ])('should convert bytes to uint64', async (a) => { const avmResult = await getAvmResult({ appClient }, 'verify_btoi', asUint8Array(a)) const result = op.btoi(a) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512)), Bytes(internal.encodingUtil.bigIntToUint8Array(MAX_UINT512 * MAX_UINT512, 128)), - Bytes(new Uint8Array(Array(5).fill(0x00).concat(Array(4).fill(0x0f)))), + Bytes(Array(5).fill(0x00).concat(Array(4).fill(0x0f))), ])('should throw error when input overflows', async (a) => { const errorRegex = new RegExp(`btoi arg too long, got \\[${a.length.valueOf()}\\]bytes`) await expect(getAvmResultRaw({ appClient }, 'verify_btoi', asUint8Array(a))).rejects.toThrow(errorRegex) @@ -167,10 +173,10 @@ describe('Pure op codes', async () => { }) describe('bzero', async () => { - test.each([0, 1, 42, MAX_BYTES_SIZE])('should retrun a zero filled bytes value of the given size', async (a) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_bzero', a))! + test.each([0, 1, 42, MAX_BYTES_SIZE])('should return a zero filled bytes value of the given size', async (a) => { + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_bzero', a))! const result = op.bzero(a) - const resultHash = getSha256Hash(asUint8Array(result)) + const resultHash = Bytes(getSha256Hash(asUint8Array(result))) expect(resultHash).toEqual(avmResult) }) @@ -181,7 +187,7 @@ describe('Pure op codes', async () => { 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 over or underflow') + expect(() => op.bzero(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) @@ -196,26 +202,28 @@ describe('Pure op codes', async () => { ['1', '0', 0, MAX_BYTES_SIZE - 2], ['1', '0', MAX_BYTES_SIZE - 2, 0], ])('should retrun concatenated bytes', async (a, b, padASize, padBSize) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_concat', asUint8Array(a), asUint8Array(b), padASize, padBSize))! + const avmResult = abiAsBytes( + await getAvmResult({ appClient }, 'verify_concat', asUint8Array(a), asUint8Array(b), padASize, padBSize), + )! - const paddedA = getPaddedUint8Array(padASize, a) - const paddedB = getPaddedUint8Array(padBSize, b) + const paddedA = getPaddedBytes(padASize, a) + const paddedB = getPaddedBytes(padBSize, b) const result = op.concat(paddedA, paddedB) - const resultHash = getSha256Hash(asUint8Array(result)) + const resultHash = Bytes(getSha256Hash(asUint8Array(result))) expect(resultHash).toEqual(avmResult) }) test.each([ - ['1', '0', MAX_BYTES_SIZE, 0], - ['1', '1', MAX_BYTES_SIZE, MAX_BYTES_SIZE], - ['1', '0', 0, MAX_BYTES_SIZE], + ['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 = getPaddedUint8Array(padASize, a) - const paddedB = getPaddedUint8Array(padBSize, b) + const paddedA = getPaddedBytes(padASize, a) + const paddedB = getPaddedBytes(padBSize, b) expect(() => op.concat(paddedA, paddedB)).toThrow(/Bytes length \d+ exceeds maximum length/) }) @@ -249,7 +257,7 @@ describe('Pure op codes', async () => { [MAX_UINT512 * 2n, 1, MAX_UINT512 * 2n, 1], ])('should throw error when input overflows', async (a, b, c, d) => { await expect(getAvmResultRaw({ appClient }, 'verify_divmodw', a, b, c, d)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.divmodw(a, b, c, d)).toThrow('Uint64 over or underflow') + expect(() => op.divmodw(a, b, c, d)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ @@ -280,7 +288,7 @@ describe('Pure op codes', async () => { ])('should calculate div result', async (a, b, c) => { const avmResult = await getAvmResult({ appClient }, 'verify_divw', a, b, c) const result = op.divw(a, b, c) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ @@ -306,7 +314,7 @@ describe('Pure op codes', async () => { [MAX_UINT512 * 2n, 1, MAX_UINT512 * 2n], ])('should throw error when input overflows', async (a, b, c) => { await expect(getAvmResultRaw({ appClient }, 'verify_divw', a, b, c)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.divw(a, b, c)).toThrow('Uint64 over or underflow') + expect(() => op.divw(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ @@ -316,7 +324,7 @@ describe('Pure op codes', async () => { [MAX_UINT64, MAX_UINT64, MAX_UINT64], ])('should throw error when result overflows', async (a, b, c) => { await expect(getAvmResultRaw({ appClient }, 'verify_divw', a, b, c)).rejects.toThrow('divw overflow') - expect(() => op.divw(a, b, c)).toThrow('Uint64 over or underflow') + expect(() => op.divw(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) @@ -330,7 +338,7 @@ describe('Pure op codes', async () => { ])('should calculate the exponentiation result', async (a, b) => { const avmResult = await getAvmResult({ appClient }, 'verify_exp', a, b) const result = op.exp(a, b) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ @@ -339,7 +347,7 @@ describe('Pure op codes', async () => { [2, 64], ])('should throw error when result overflows', async (a, b) => { await expect(getAvmResultRaw({ appClient }, 'verify_exp', a, b)).rejects.toThrow('overflow') - expect(() => op.exp(a, b)).toThrow('Uint64 over or underflow') + expect(() => op.exp(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ @@ -349,7 +357,7 @@ describe('Pure op codes', async () => { [MAX_UINT512 * 2n, 1], ])('should throw error when input overflows', async (a, b) => { await expect(getAvmResultRaw({ appClient }, 'verify_exp', a, b)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.exp(a, b)).toThrow('Uint64 over or underflow') + expect(() => op.exp(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) it('0 ** 0 is not supported', async () => { @@ -378,7 +386,7 @@ describe('Pure op codes', async () => { [2, 128], ])('should throw error when result overflows', async (a, b) => { await expect(getAvmResultRaw({ appClient }, 'verify_expw', a, b)).rejects.toThrow('overflow') - expect(() => op.expw(a, b)).toThrow('Uint64 over or underflow') + expect(() => op.expw(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ @@ -388,7 +396,7 @@ describe('Pure op codes', async () => { [MAX_UINT512 * 2n, 1], ])(`should throw error when input overflows`, async (a, b) => { await expect(getAvmResultRaw({ appClient }, 'verify_expw', a, b)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.expw(a, b)).toThrow('Uint64 over or underflow') + expect(() => op.expw(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) it('0 ** 0 is not supported', async () => { @@ -409,20 +417,20 @@ describe('Pure op codes', async () => { [256, 3], ])(`should extract bytes from the input`, async (b, c) => { const a = 'hello, world'.repeat(30) - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_extract', asUint8Array(a), b, c))! + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_extract', asUint8Array(a), b, c))! let result = op.extract(a, Uint64(b), Uint64(c)) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) if (c) { result = op.extract(a, b, c) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) } }) test.each(['hello, world', 'hi'])('should work to extract bytes from 2 to end', async (a) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_extract_from_2', asUint8Array(a)))! + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_extract_from_2', asUint8Array(a)))! const result = op.extract(a, 2, 0) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) }) test.each([ @@ -433,7 +441,7 @@ describe('Pure op codes', async () => { ])(`should throw error when input overflows`, async (b, c) => { 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 over or underflow') + expect(() => op.extract(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ @@ -451,29 +459,29 @@ describe('Pure op codes', async () => { describe('extractUint16', async () => { test.each([ [intToBytes(256), 0], - [getPaddedUint8Array(2, intToBytes(256)), 2], + [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) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ - [getPaddedUint8Array(2, intToBytes(256)), MAX_UINT64 + 1n], + [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 over or underflow') + expect(() => op.extractUint16(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ [intToBytes(0), 0], [intToBytes(0), 1], [intToBytes(256), 1], - [getPaddedUint8Array(2, intToBytes(256)), 3], + [getPaddedBytes(2, intToBytes(256)), 3], [intToBytes(MAX_UINT64), 8], [intToBytes(MAX_UINT512), 65], ])(`should throw error when input is invalid`, async (a, b) => { @@ -484,30 +492,30 @@ describe('Pure op codes', async () => { describe('extractUint32', async () => { test.each([ - [new Uint8Array([0x0f, 0x66, 0x66, 0x66]), 0], - [getPaddedUint8Array(4, intToBytes(256)), 2], + [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) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ - [getPaddedUint8Array(4, intToBytes(256)), MAX_UINT64 + 1n], + [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 over or underflow') + expect(() => op.extractUint32(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ [intToBytes(0), 0], [intToBytes(0), 1], [intToBytes(256), 1], - [getPaddedUint8Array(4, intToBytes(256)), 3], + [getPaddedBytes(4, intToBytes(256)), 3], [intToBytes(MAX_UINT64), 8], [intToBytes(MAX_UINT512), 65], ])(`should throw error when input is invalid`, async (a, b) => { @@ -518,30 +526,30 @@ describe('Pure op codes', async () => { describe('extractUint64', async () => { test.each([ - [new Uint8Array([0x0f, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66]), 0], - [getPaddedUint8Array(8, intToBytes(256)), 2], + [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) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ - [getPaddedUint8Array(8, intToBytes(256)), MAX_UINT64 + 1n], + [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 over or underflow') + expect(() => op.extractUint64(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ [intToBytes(0), 0], [intToBytes(0), 1], [intToBytes(256), 1], - [getPaddedUint8Array(8, intToBytes(256)), 3], + [getPaddedBytes(8, intToBytes(256)), 3], [intToBytes(MAX_UINT64), 8], [intToBytes(MAX_UINT512), 65], ])(`should throw error when input is invalid`, async (a, b) => { @@ -552,12 +560,12 @@ describe('Pure op codes', async () => { describe('getBit', async () => { test.each([ - [new Uint8Array([0x00]), 0], - [getPaddedUint8Array(2, intToBytes(256)), 3], - [getPaddedUint8Array(2, intToBytes(256)), 0], - [getPaddedUint8Array(2, intToBytes(256)), 11], - [getPaddedUint8Array(2, intToBytes(65535)), 31], - [getPaddedUint8Array(2, intToBytes(65535)), 24], + [Bytes([0x00]), 0], + [getPaddedBytes(2, intToBytes(256)), 3], + [getPaddedBytes(2, intToBytes(256)), 0], + [getPaddedBytes(2, intToBytes(256)), 11], + [getPaddedBytes(2, intToBytes(65535)), 31], + [getPaddedBytes(2, intToBytes(65535)), 24], [intToBytes(MAX_UINT64), 63], [intToBytes(MAX_UINT64 - 1n), 63], [intToBytes(MAX_UINT512), 511], @@ -567,11 +575,11 @@ describe('Pure op codes', async () => { ])(`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) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ - [new Uint8Array([0x00]), 8], + [Bytes([0x00]), 8], [intToBytes(MAX_UINT64), 64], [intToBytes(MAX_UINT64 - 1n), 64], [intToBytes(MAX_UINT512), 512], @@ -599,7 +607,7 @@ describe('Pure op codes', async () => { ])(`should get the bit at the given index of uint64 value`, async (a, b) => { const avmResult = await getAvmResult({ appClient }, 'verify_getbit_uint64', a, b) const result = op.getBit(a, b) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ @@ -613,11 +621,11 @@ describe('Pure op codes', async () => { describe('getByte', async () => { test.each([ - [new Uint8Array([0x00]), 0], - [getPaddedUint8Array(2, intToBytes(256)), 3], - [getPaddedUint8Array(2, intToBytes(256)), 0], - [getPaddedUint8Array(2, intToBytes(256)), 1], - [getPaddedUint8Array(2, intToBytes(65530)), 3], + [Bytes([0x00]), 0], + [getPaddedBytes(2, intToBytes(256)), 3], + [getPaddedBytes(2, intToBytes(256)), 0], + [getPaddedBytes(2, intToBytes(256)), 1], + [getPaddedBytes(2, intToBytes(65530)), 3], [intToBytes(MAX_UINT64), 7], [intToBytes(MAX_UINT64 - 1n), 0], [intToBytes(MAX_UINT64 - 1n), 7], @@ -627,11 +635,11 @@ describe('Pure op codes', async () => { ])('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) - expect(result.valueOf()).toEqual(avmResult) + expect(result).toEqual(avmResult) }) test.each([ - [new Uint8Array([0x00]), 8], + [Bytes([0x00]), 8], [intToBytes(MAX_UINT64), 64], [intToBytes(MAX_UINT64 - 1n), 64], [intToBytes(MAX_UINT512), 512], @@ -646,14 +654,14 @@ describe('Pure op codes', async () => { describe('itob', async () => { test.each([0, 42, 100n, 256, 65535, MAX_UINT64])('should convert uint64 to bytes', async (a) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_itob', a))! + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_itob', a))! const result = op.itob(a) - expect(asUint8Array(result)).toEqual(avmResult) + 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 over or underflow') + expect(() => op.itob(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) @@ -681,7 +689,7 @@ describe('Pure op codes', async () => { [MAX_UINT512 * 2n, 0], ])(`should throw error when input overflows`, async (a, b) => { await expect(getAvmResult({ appClient }, 'verify_mulw', a, b)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.mulw(a, b)).toThrow('Uint64 over or underflow') + expect(() => op.mulw(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) @@ -695,9 +703,9 @@ describe('Pure op codes', async () => { ['hello, world.', 0, 'H'], ['', 0, ''], ])(`should replace bytes in the input`, async (a, b, c) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_replace', asUint8Array(a), b, asUint8Array(c)))! + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_replace', asUint8Array(a), b, asUint8Array(c)))! const result = op.replace(a, b, c) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) }) test.each([ @@ -720,28 +728,24 @@ describe('Pure op codes', async () => { ['one', 'two', 2], ['one', 'two', true], ['one', 'two', false], - [new Uint8Array([0x00, 0x00, 0xff]), new Uint8Array([0xff]), 0n], - [new Uint8Array([0x00, 0x00, 0xff]), new Uint8Array([0xff]), 1n], + [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) => { - const avmResult = (await getAvmResultRaw( - { appClient }, - 'verify_select_bytes', - asUint8Array(a), - asUint8Array(b), - c === true ? 1 : c === false ? 0 : c, - ))! + const avmResult = abiAsBytes( + await getAvmResult({ appClient }, 'verify_select_bytes', asUint8Array(a), asUint8Array(b), c === true ? 1 : c === false ? 0 : c), + )! const result = op.select(a, b, c) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) }) test.each([ - [new Uint8Array([0x00, 0x00, 0xff]), new Uint8Array([0xff]), MAX_UINT64 + 1n], - [new Uint8Array([0x00, 0x00, 0xff]), new Uint8Array([0xff]), MAX_UINT512], + [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 over or underflow') + expect(() => op.select(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ @@ -753,7 +757,7 @@ describe('Pure op codes', async () => { ])('should select uint64 according to the input', async (a, b, c) => { 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.valueOf()).toEqual(avmResult) + expect(result).toEqual(avmResult) }) test.each([ @@ -761,18 +765,18 @@ describe('Pure op codes', async () => { [MAX_UINT512, MAX_UINT512, MAX_UINT512], ])(`should throw error when input overflows to select uint64`, async (a, b, c) => { await expect(getAvmResult({ appClient }, 'verify_select_uint64', a, b, c)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.select(a, b, c)).toThrow('Uint64 over or underflow') + expect(() => op.select(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) describe('setBit', async () => { test.each([ - [new Uint8Array([0x00]), 0, 1], - [getPaddedUint8Array(2, intToBytes(256)), 3, 1], - [getPaddedUint8Array(2, intToBytes(256)), 0, 1], - [getPaddedUint8Array(2, intToBytes(256)), 11, 1], - [getPaddedUint8Array(2, intToBytes(65535)), 31, 0], - [getPaddedUint8Array(2, intToBytes(65535)), 24, 0], + [Bytes([0x00]), 0, 1], + [getPaddedBytes(2, intToBytes(256)), 3, 1], + [getPaddedBytes(2, intToBytes(256)), 0, 1], + [getPaddedBytes(2, intToBytes(256)), 11, 1], + [getPaddedBytes(2, intToBytes(65535)), 31, 0], + [getPaddedBytes(2, intToBytes(65535)), 24, 0], [intToBytes(MAX_UINT64), 63, 0], [intToBytes(MAX_UINT64 - 1n), 63, 1], [intToBytes(MAX_UINT512), 511, 0], @@ -780,13 +784,13 @@ describe('Pure op codes', async () => { [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 getAvmResultRaw({ appClient }, 'verify_setbit_bytes', asUint8Array(a), b, c))! + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_setbit_bytes', asUint8Array(a), b, c))! const result = op.setBit(a, b, c) as bytes - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) }) test.each([ - [new Uint8Array([0x00]), 8, 1], + [Bytes([0x00]), 8, 1], [intToBytes(MAX_UINT64), 64, 0], [intToBytes(MAX_UINT64 - 1n), 64, 1], [intToBytes(MAX_UINT512), 512, 0], @@ -799,7 +803,7 @@ describe('Pure op codes', async () => { }) it('should throw error when input is invalid', async () => { - const a = new Uint8Array([0x00]) + const a = Bytes([0x00]) const b = 0 const c = 2 await expect(getAvmResultRaw({ appClient }, 'verify_setbit_bytes', asUint8Array(a), b, c)).rejects.toThrow('setbit value > 1') @@ -822,7 +826,7 @@ describe('Pure op codes', async () => { ])('should set the bit at the given index of uint64 value', async (a, b, c) => { const avmResult = await getAvmResult({ appClient }, 'verify_setbit_uint64', a, b, c) const result = op.setBit(a, b, c) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ @@ -844,12 +848,12 @@ describe('Pure op codes', async () => { describe('setByte', async () => { test.each([ - [new Uint8Array([0x00]), 0, 1], - [getPaddedUint8Array(2, intToBytes(256)), 3, 1], - [getPaddedUint8Array(2, intToBytes(256)), 0, 1], - [getPaddedUint8Array(2, intToBytes(256)), 1, 255], - [getPaddedUint8Array(2, intToBytes(65535)), 2, 0], - [getPaddedUint8Array(2, intToBytes(65535)), 2, 100], + [Bytes([0x00]), 0, 1], + [getPaddedBytes(2, intToBytes(256)), 3, 1], + [getPaddedBytes(2, intToBytes(256)), 0, 1], + [getPaddedBytes(2, intToBytes(256)), 1, 255], + [getPaddedBytes(2, intToBytes(65535)), 2, 0], + [getPaddedBytes(2, intToBytes(65535)), 2, 100], [intToBytes(MAX_UINT64), 7, 0], [intToBytes(MAX_UINT64 - 1n), 0, 42], [intToBytes(MAX_UINT512), 63, 0], @@ -857,13 +861,13 @@ describe('Pure op codes', async () => { [intToBytes(MAX_UINT64), 0, 0], [intToBytes(MAX_UINT512), 0, 0], ])(`should set bytes in the input`, async (a, b, c) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_setbyte', asUint8Array(a), b, c))! + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_setbyte', asUint8Array(a), b, c))! const result = op.setByte(a, b, c) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) }) test.each([ - [new Uint8Array([0x00]), 8, 1], + [Bytes([0x00]), 8, 1], [intToBytes(MAX_UINT64), 64, 0], [intToBytes(MAX_UINT64 - 1n), 64, 1], [intToBytes(MAX_UINT512), 512, 0], @@ -876,7 +880,7 @@ describe('Pure op codes', async () => { }) it('should throw error when input is invalid', async () => { - const a = new Uint8Array([0x00]) + const a = Bytes([0x00]) const b = 0 const c = 256 await expect(getAvmResultRaw({ appClient }, 'verify_setbyte', asUint8Array(a), b, c)).rejects.toThrow('setbyte value > 255') @@ -897,7 +901,7 @@ describe('Pure op codes', async () => { ])(`should shift left the input`, async (a, b) => { const avmResult = await getAvmResult({ appClient }, 'verify_shl', a, b) const result = op.shl(a, b) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ @@ -907,7 +911,7 @@ describe('Pure op codes', async () => { [MAX_UINT512 * 2n, 0], ])(`should throw error when input overflows`, async (a, b) => { await expect(getAvmResult({ appClient }, 'verify_shl', a, b)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.shl(a, b)).toThrow('Uint64 over or underflow') + expect(() => op.shl(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ @@ -931,7 +935,7 @@ describe('Pure op codes', async () => { ])('should shift right the input', async (a, b) => { const avmResult = await getAvmResult({ appClient }, 'verify_shr', a, b) const result = op.shr(a, b) - expect(result.valueOf()).toBe(avmResult) + expect(result).toEqual(avmResult) }) test.each([ @@ -941,7 +945,7 @@ describe('Pure op codes', async () => { [MAX_UINT512 * 2n, 1], ])('should throw error when input overflows', async (a, b) => { await expect(getAvmResult({ appClient }, 'verify_shr', a, b)).rejects.toThrow(avmIntArgOverflowError) - expect(() => op.shr(a, b)).toThrow('Uint64 over or underflow') + expect(() => op.shr(a, b)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) test.each([ @@ -957,12 +961,12 @@ describe('Pure op codes', 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.valueOf()).toBe(avmResult) + 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 over or underflow') + expect(() => op.sqrt(a)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) @@ -978,9 +982,9 @@ describe('Pure op codes', async () => { ['hello, world.', 0, 13], ['', 0, 0], ])('should extract substring from the input', async (a, b, c) => { - const avmResult = (await getAvmResultRaw({ appClient }, 'verify_substring', asUint8Array(a), b, c))! + const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_substring', asUint8Array(a), b, c)) const result = op.substring(a, b, c) - expect(asUint8Array(result)).toEqual(avmResult) + expect(result).toEqual(avmResult) }) test.each([ @@ -1000,7 +1004,7 @@ describe('Pure op codes', async () => { ['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 over or underflow') + expect(() => op.substring(a, b, c)).toThrow(UINT64_OVERFLOW_UNDERFLOW_MESSAGE) }) }) diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 43c3b30..3be0b43 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -1,20 +1,13 @@ -import { Account, arc4, bytes, Bytes, internal, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { Account, arc4, bytes, Bytes, internal, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' -import { - generateTestAccount, - generateTestAsset, - getAlgorandAppClient, - getAlgorandAppClientWithApp, - getAvmResult, - getLocalNetDefaultAccount, - INITIAL_BALANCE_MICRO_ALGOS, -} from './avm-invoker' - -import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import { MIN_TXN_FEE, ZERO_ADDRESS } from '../src/constants' +import { testInvariant } from '../src/errors' import { AccountCls } from '../src/impl/account' +import { InnerTxn } from '../src/impl/itxn' +import { ApplicationTransaction } from '../src/impl/transactions' import { asBigInt, asNumber, asUint64Cls } from '../src/util' import { AppExpectingEffects } from './artifacts/created-app-asset/contract.algo' import { @@ -29,9 +22,16 @@ import acctParamsAppSpecJson from './artifacts/state-ops/data/StateAcctParamsGet 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 { asUint8Array } from './util' -import { InnerTxn } from '../src/impl/itxn' -import { ApplicationTransaction } from '../src/impl/transactions' describe('State op codes', async () => { const ctx = new TestExecutionContext() @@ -57,9 +57,9 @@ describe('State op codes', async () => { ['verify_acct_total_assets', 0], ['verify_acct_total_boxes', 0], ['verify_acct_total_box_bytes', 0], - ])('should return the correct field value of the account', async (methodName, expectedValue) => { + ])('%s should return %s', async (methodName, expectedValue) => { const mockAccount = ctx.any.account({ - address: dummyAccount.addr, + address: dummyAccount, balance: Uint64(INITIAL_BALANCE_MICRO_ALGOS + 100000), minBalance: Uint64(100000), authAddress: Account(ZERO_ADDRESS), @@ -74,17 +74,17 @@ describe('State op codes', async () => { totalBoxBytes: Uint64(0), }) - const avmResult = await getAvmResult({ appClient, sendParams: { fee: AlgoAmount.Algos(1000) } }, methodName, dummyAccount.addr) - + const avmResult = await getAvmResult( + { appClient, sendParams: { fee: AlgoAmount.Algos(1000) } }, + methodName, + asUint8Array(dummyAccount.bytes), + ) + testInvariant(avmResult !== undefined, 'There must be an AVM result') const mockContract = ctx.contract.create(StateAcctParamsGetContract) const mockResult = mockContract[methodName as keyof StateAcctParamsGetContract](mockAccount) - if (mockResult instanceof AccountCls) { - expect(mockResult.bytes.valueOf()).toEqual(avmResult) - expect(mockResult.bytes.valueOf()).toEqual((expectedValue as bytes).valueOf()) - } else { - expect(mockResult.valueOf()).toEqual(avmResult) - expect(asNumber(mockResult as uint64)).toEqual(expectedValue) - } + + expect(mockResult).toEqual(avmResult) + expect(mockResult).toEqual(expectedValue) }) }) @@ -101,7 +101,7 @@ 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'], - ])('should return the correct field value of the application', async (methodName, expectedValue) => { + ])('%s should return %s', async (methodName, expectedValue) => { const application = ctx.any.application({ applicationId: app.appId, approvalProgram: Bytes(app.compiledApproval.compiledBase64ToBytes), @@ -111,25 +111,21 @@ describe('State op codes', async () => { localNumUint: Uint64(0), localNumBytes: Uint64(0), extraProgramPages: Uint64(0), - creator: Account(Bytes(dummyAccount.addr)), + creator: Account(Bytes.fromBase32(dummyAccount.addr)), }) const avmResult = await getAvmResult({ appClient, sendParams: { fee: AlgoAmount.Algos(1000) } }, methodName, app.appId) const mockContract = ctx.contract.create(StateAppParamsContract) const mockResult = mockContract[methodName as keyof StateAppParamsContract](application) - if (mockResult instanceof internal.primitives.BytesCls) { - expect([...asUint8Array(mockResult)]).toEqual(avmResult) - } else if (mockResult instanceof AccountCls) { - expect(mockResult.bytes.valueOf()).toEqual(avmResult) - const expected = - expectedValue === 'app.creator' ? application.creator : expectedValue === 'app.address' ? application.address : undefined - if (expected) { - expect(mockResult.bytes.valueOf()).toEqual(expected.bytes.valueOf()) - } - } else { - expect(mockResult.valueOf()).toEqual(avmResult) - expect(asNumber(mockResult as uint64)).toEqual(expectedValue) + expect(mockResult).toEqual(avmResult) + + if (expectedValue === 'app.creator') { + expect(mockResult).toEqual(application.creator) + } else if (expectedValue === 'app.address') { + expect(mockResult).toEqual(application.address) + } else if (expectedValue !== undefined) { + expect(mockResult).toEqual(expectedValue) } }) }) @@ -184,7 +180,7 @@ describe('State op codes', async () => { ['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 = dummyAccount.addr + const creator = Account(Bytes.fromBase32(dummyAccount.addr)) const metadataHash = Bytes(`test${' '.repeat(28)}`) const mockAsset = ctx.any.asset({ total: Uint64(100), @@ -193,7 +189,7 @@ describe('State op codes', async () => { unitName: Bytes('UNIT'), url: Bytes('https://algorand.co'), metadataHash: metadataHash, - creator: Account(Bytes(creator)), + creator, }) const dummyAsset = await generateTestAsset({ @@ -212,17 +208,11 @@ describe('State op codes', async () => { const mockContract = ctx.contract.create(StateAssetParamsContract) const mockResult = mockContract[methodName as keyof StateAssetParamsContract](mockAsset) - if (mockResult instanceof internal.primitives.BytesCls) { - expect([...asUint8Array(mockResult)]).toEqual(avmResult) - expect(asUint8Array(mockResult)).toEqual(asUint8Array(expectedValue as bytes)) - } else if (mockResult instanceof AccountCls) { - expect(mockResult.bytes.valueOf()).toEqual(avmResult) - - const expectedString = expectedValue === 'creator' ? creator : (expectedValue as bytes).valueOf() - expect(mockResult.bytes.valueOf()).toEqual(expectedString) + expect(mockResult).toEqual(avmResult) + if (expectedValue === 'creator') { + expect(mockResult).toEqual(creator) } else { - expect(mockResult.valueOf()).toEqual(avmResult) - expect(mockResult.valueOf()).toEqual(expectedValue) + expect(mockResult).toEqual(expectedValue) } }) }) @@ -336,7 +326,7 @@ describe('State op codes', async () => { expect(asNumber(paymentItxn.amount)).toEqual(1000) expect(paymentItxn.sender).toEqual(ctx.ledger.getApplicationForContract(contract).address) expect(paymentItxn.type).toEqual(TransactionType.Payment) - expect(appItxn.typeBytes).toEqual(asUint64Cls(TransactionType.Payment).toBytes()) + expect(paymentItxn.typeBytes).toEqual(asUint64Cls(TransactionType.Payment).toBytes()) // Test common fields for both transactions ;[appItxn, paymentItxn].forEach((t: InnerTxn) => { diff --git a/tests/util.ts b/tests/util.ts index af67b5e..856ec0c 100644 --- a/tests/util.ts +++ b/tests/util.ts @@ -1,4 +1,5 @@ import { Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' +import { ABIValue } from 'algosdk' import { createHash } from 'crypto' export const padUint8Array = (arr: Uint8Array, padSize: number): Uint8Array => { @@ -10,18 +11,33 @@ export const padUint8Array = (arr: Uint8Array, padSize: number): Uint8Array => { export const asUint8Array = (value: internal.primitives.StubBytesCompat): Uint8Array => internal.primitives.BytesCls.fromCompat(value).asUint8Array() -export const base64Encode = (value: Uint8Array | string): bytes => Bytes(Buffer.from(value).toString('base64')) +export const base64Encode = (value: internal.primitives.StubBytesCompat): bytes => + Bytes(Buffer.from(asUint8Array(value)).toString('base64')) -export const base64UrlEncode = (value: Uint8Array | string): bytes => Bytes(Buffer.from(value).toString('base64url')) +export const base64UrlEncode = (value: internal.primitives.StubBytesCompat): bytes => + Bytes(Buffer.from(asUint8Array(value)).toString('base64url')) export const getSha256Hash = (value: Uint8Array): Uint8Array => new Uint8Array(createHash('sha256').update(value).digest()) -export const getPaddedUint8Array = (padSize: number, value: internal.primitives.StubBytesCompat): Uint8Array => { +export const getPaddedBytes = (padSize: number, value: internal.primitives.StubBytesCompat): bytes => { const uint8ArrayValue = asUint8Array(value) const result = new Uint8Array(padSize + uint8ArrayValue.length) result.set([...Array(padSize).fill(0x00), ...uint8ArrayValue]) - return result + return Bytes(result) } export const intToBytes = (value: internal.primitives.StubBigUintCompat): internal.primitives.BytesCls => internal.primitives.BigUintCls.fromCompat(value).toBytes() + +export const abiAsBytes = (value: ABIValue) => { + if (Array.isArray(value) && value.every((i) => typeof i === 'number')) { + return Bytes(new Uint8Array(value)) + } + if (value instanceof Uint8Array) { + return Bytes(value) + } + if (typeof value === 'string') { + return Bytes(value) + } + throw new Error(`Value cannot be converted to bytes`) +} From 9d05cb3672a80c8dcf7453371ef2c0d7c04b4516 Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Wed, 9 Oct 2024 20:51:06 -0700 Subject: [PATCH 21/85] chore: Lint fix --- tests/avm-invoker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/avm-invoker.ts b/tests/avm-invoker.ts index 3274f4f..7aa6005 100644 --- a/tests/avm-invoker.ts +++ b/tests/avm-invoker.ts @@ -12,7 +12,7 @@ import { randomUUID } from 'crypto' import { asUint64, getRandomNumber, Lazy } from '../src/util' algokit.Config.configure({ logger: nullLogger }) -const ARC4_PREFIX_LENGTH = 2 + const algorandClient = Lazy(() => algokit.AlgorandClient.defaultLocalNet()) export const INITIAL_BALANCE_MICRO_ALGOS = Number(20e6) From 226d4b9dc0d3db9673b5ebc8661fa765c584ebd9 Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Wed, 9 Oct 2024 21:08:44 -0700 Subject: [PATCH 22/85] build: Bundle and patch typescript version --- .github/workflows/release.yml | 5 +- package-lock.json | 289 +++++++++++++++++++++++++++++++++ package.json | 9 +- patches/typescript+5.6.2.patch | 34 ++++ 4 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 patches/typescript+5.6.2.patch diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1af00be..d258731 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,6 +52,10 @@ jobs: with: path: artifacts + - name: Install @algorandfoundation/algorand-typescript-testing dependencies and patch for bundling + run: npm i --include=prod && npx patch-package --patch-dir ../../patches + working-directory: artifacts/algo-ts-testing + - name: Generate semantic version for @algorandfoundation/algorand-typescript-testing run: npx semantic-release env: @@ -59,7 +63,6 @@ jobs: - name: Publish @algorandfoundation/algorand-typescript-testing uses: JS-DevTools/npm-publish@v3 - id: publish-puya-ts with: token: ${{ secrets.NPM_TOKEN }} package: artifacts/algo-ts-testing/package.json diff --git a/package-lock.json b/package-lock.json index 47a0266..ca319fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "npm-run-all": "4.1.5", + "patch-package": "^8.0.0", "prettier": "3.3.3", "rimraf": "6.0.1", "rollup": "^4.24.0", @@ -2983,6 +2984,13 @@ "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.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", @@ -3219,6 +3227,16 @@ "node": ">=8" } }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -3460,6 +3478,22 @@ "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", @@ -4922,6 +4956,16 @@ "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", @@ -5841,6 +5885,22 @@ "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", @@ -6072,6 +6132,19 @@ "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": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -6253,12 +6326,38 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", + "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "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", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json-stable-stringify/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/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -6272,6 +6371,16 @@ "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", @@ -6309,6 +6418,16 @@ "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", @@ -9695,6 +9814,23 @@ "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", @@ -9712,6 +9848,16 @@ "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/p-each-series": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", @@ -9890,6 +10036,123 @@ "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/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/patch-package/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==", + "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_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/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/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/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -11692,6 +11955,19 @@ "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-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -12751,6 +13027,19 @@ "node": ">=10" } }, + "node_modules/yaml": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/package.json b/package.json index 9c6441a..b0f3f85 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "main": "index.js", "types": "src/index.ts", "scripts": { + "postinstall": "patch-package", "audit": "better-npm-audit audit", "format": "prettier --write .", "lint": "eslint \"src/**/*.ts\"", @@ -48,6 +49,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "npm-run-all": "4.1.5", + "patch-package": "^8.0.0", "prettier": "3.3.3", "rimraf": "6.0.1", "rollup": "^4.24.0", @@ -60,8 +62,8 @@ "tslib": "^2.6.2" }, "dependencies": { - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.9", "@algorandfoundation/algokit-utils": "^6.2.1", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.9", "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", "algosdk": "^2.9.0", "elliptic": "^6.5.7", @@ -69,5 +71,8 @@ "js-sha3": "^0.9.3", "js-sha512": "^0.9.0", "tweetnacl": "^1.0.3" - } + }, + "bundleDependencies": [ + "typescript" + ] } diff --git a/patches/typescript+5.6.2.patch b/patches/typescript+5.6.2.patch new file mode 100644 index 0000000..9712991 --- /dev/null +++ b/patches/typescript+5.6.2.patch @@ -0,0 +1,34 @@ +diff --git a/node_modules/typescript/lib/typescript.d.ts b/node_modules/typescript/lib/typescript.d.ts +index 963c573..299a8a4 100644 +--- a/node_modules/typescript/lib/typescript.d.ts ++++ b/node_modules/typescript/lib/typescript.d.ts +@@ -6116,6 +6116,7 @@ declare namespace ts { + getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; + getIndexInfosOfType(type: Type): readonly IndexInfo[]; + getIndexInfosOfIndexSymbol: (indexSymbol: Symbol) => 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 90f3266..9daa319 100644 +--- a/node_modules/typescript/lib/typescript.js ++++ b/node_modules/typescript/lib/typescript.js +@@ -50171,6 +50171,7 @@ function createTypeChecker(host) { + getGlobalDiagnostics, + getRecursionIdentity, + getUnmatchedProperties, ++ getTypeArgumentsForResolvedSignature, + getTypeOfSymbolAtLocation: (symbol, locationIn) => { + const location = getParseTreeNode(locationIn); + return location ? getTypeOfSymbolAtLocation(symbol, location) : errorType; +@@ -92895,6 +92896,9 @@ function createTypeChecker(host) { + Debug.assert(specifier && nodeIsSynthesized(specifier) && specifier.text === "tslib", `Expected sourceFile.imports[0] to be the synthesized tslib import`); + return specifier; + } ++ function getTypeArgumentsForResolvedSignature(signature) { ++ return signature.mapper && instantiateTypes((signature.target ?? signature).typeParameters ?? [], signature.mapper); ++ } + } + function isNotAccessor(declaration) { + return !isAccessor(declaration); From d4be90e67367a158416f378ee91d6cfaf9dc7602 Mon Sep 17 00:00:00 2001 From: Tristan Menzel Date: Wed, 9 Oct 2024 21:18:43 -0700 Subject: [PATCH 23/85] build: Don't bundle typescript, just patch it locally --- .github/workflows/release.yml | 4 ---- package.json | 5 +---- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d258731..f651e06 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,10 +52,6 @@ jobs: with: path: artifacts - - name: Install @algorandfoundation/algorand-typescript-testing dependencies and patch for bundling - run: npm i --include=prod && npx patch-package --patch-dir ../../patches - working-directory: artifacts/algo-ts-testing - - name: Generate semantic version for @algorandfoundation/algorand-typescript-testing run: npx semantic-release env: diff --git a/package.json b/package.json index b0f3f85..8129992 100644 --- a/package.json +++ b/package.json @@ -71,8 +71,5 @@ "js-sha3": "^0.9.3", "js-sha512": "^0.9.0", "tweetnacl": "^1.0.3" - }, - "bundleDependencies": [ - "typescript" - ] + } } From fff91262b4228e57f16674be36d64c5090accfb4 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 14 Oct 2024 14:09:31 +0800 Subject: [PATCH 24/85] add example contract for scratch storage --- examples/scratch-storage/contract.algo.ts | 23 ++++++++++++++++++ examples/scratch-storage/contract.spec.ts | 29 +++++++++++++++++++++++ package-lock.json | 1 + package.json | 4 ++-- src/subcontexts/transaction-context.ts | 4 ++++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 examples/scratch-storage/contract.algo.ts create mode 100644 examples/scratch-storage/contract.spec.ts diff --git a/examples/scratch-storage/contract.algo.ts b/examples/scratch-storage/contract.algo.ts new file mode 100644 index 0000000..4fd0290 --- /dev/null +++ b/examples/scratch-storage/contract.algo.ts @@ -0,0 +1,23 @@ +import { arc4, assert, BaseContract, Bytes, op, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' + +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.loadBytes(2) === Bytes('Hello World')) + return true + } +} + +export class SimpleScratchSlotsContract extends BaseContract { + approvalProgram(): boolean | uint64 { + assert(op.Scratch.loadUint64(1) === Uint64(5)) + assert(op.Scratch.loadBytes(2) === Bytes('Hello World')) + return Uint64(1) + } + clearStateProgram(): boolean | uint64 { + return Uint64(1) + } +} diff --git a/examples/scratch-storage/contract.spec.ts b/examples/scratch-storage/contract.spec.ts new file mode 100644 index 0000000..8687fad --- /dev/null +++ b/examples/scratch-storage/contract.spec.ts @@ -0,0 +1,29 @@ +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, expect, it } from 'vitest' +import { ScratchSlotsContract, SimpleScratchSlotsContract } from './contract.algo' +import { Bytes, Uint64 } from '@algorandfoundation/algorand-typescript' + +describe('ScratchSlotsContract', () => { + const ctx = new TestExecutionContext() + afterEach(() => { + ctx.reset() + }) + it('should be able to store data', async () => { + const contract = ctx.contract.create(ScratchSlotsContract) + const result = contract.storeData() + expect(result).toBe(true) + + const scratchSpace = ctx.txn.lastGroup.getScratchSpace() + + expect(scratchSpace[1]).toEqual(Uint64(5)) + expect(scratchSpace[2]).toEqual(Bytes('Hello World')) + }) + + it('should be able to load stored data', async () => { + const contract = ctx.contract.create(SimpleScratchSlotsContract) + ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: [Uint64(0), Uint64(5), Bytes('Hello World')] })]).execute(() => { + const result = contract.approvalProgram() + expect(result).toEqual(Uint64(1)) + }) + }) +}) diff --git a/package-lock.json b/package-lock.json index ca319fc..e700db0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "@algorandfoundation/algorand-typescript-testing", "version": "1.0.0", + "hasInstallScript": true, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.9", diff --git a/package.json b/package.json index 8129992..8dbbd3f 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "postinstall": "patch-package", "audit": "better-npm-audit audit", "format": "prettier --write .", - "lint": "eslint \"src/**/*.ts\"", - "lint:fix": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix", + "lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" \"examples/**/*.ts\"", + "lint:fix": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" \"examples/**/*.ts\" --fix", "build": "run-s build:*", "build:0-clean": "rimraf dist coverage", "build:1-lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" --max-warnings 0", diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index e1cfd4f..1708814 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -162,6 +162,10 @@ export class TransactionGroup { return this.constructingItxnGroup.at(-1)! } + getScratchSpace() { + return this.activeTransaction.scratchSpace + } + getScratchSlot(index: internal.primitives.StubUint64Compat): bytes | uint64 { return this.activeTransaction.getScratchSlot(index) } From 627c06e67faf58a5a66ae008d97a288c479c99b4 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 14 Oct 2024 15:13:23 +0800 Subject: [PATCH 25/85] implement gloadBytes, gloadUint64, Block, and add tests for those --- src/impl/block.ts | 13 +++++++ src/impl/index.ts | 3 +- src/impl/scratch.ts | 28 +++++++++++++- src/impl/txn.ts | 11 +----- src/subcontexts/ledger-context.ts | 26 +++++++++++++ tests/state-op-codes.spec.ts | 62 +++++++++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 src/impl/block.ts diff --git a/src/impl/block.ts b/src/impl/block.ts new file mode 100644 index 0000000..0d232bf --- /dev/null +++ b/src/impl/block.ts @@ -0,0 +1,13 @@ +import { bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' +import { itob } from './pure' +import { asUint64 } from '../util' + +export const Block: internal.opTypes.BlockType = { + blkSeed: function (a: internal.primitives.StubUint64Compat): bytes { + return itob(lazyContext.ledger.getBlockContent(a).seed) + }, + blkTimestamp: function (a: internal.primitives.StubUint64Compat): uint64 { + return asUint64(lazyContext.ledger.getBlockContent(a).timestamp) + }, +} diff --git a/src/impl/index.ts b/src/impl/index.ts index 35d1294..e280392 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -8,4 +8,5 @@ export { GTxn } from './gtxn' export * from './pure' export { Txn, gaid } from './txn' export { GITxn, ITxn, ITxnCreate } from './itxn' -export { Scratch } from './scratch' +export { Scratch, gloadBytes, gloadUint64 } from './scratch' +export { Block } from './block' diff --git a/src/impl/scratch.ts b/src/impl/scratch.ts index cc2e3ab..fb1ded7 100644 --- a/src/impl/scratch.ts +++ b/src/impl/scratch.ts @@ -1,20 +1,44 @@ import { bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' +export const gloadUint64: internal.opTypes.GloadUint64Type = ( + a: internal.primitives.StubUint64Compat, + b: internal.primitives.StubUint64Compat, +): uint64 => { + const txn = lazyContext.activeGroup.getTransaction(a) + const result = txn.getScratchSlot(b) + if (result instanceof internal.primitives.Uint64Cls) { + return result as uint64 + } + throw new internal.errors.InternalError('invalid scratch slot type') +} + +export const gloadBytes: internal.opTypes.GloadBytesType = ( + a: internal.primitives.StubUint64Compat, + b: internal.primitives.StubUint64Compat, +): bytes => { + const txn = lazyContext.activeGroup.getTransaction(a) + const result = txn.getScratchSlot(b) + if (result instanceof internal.primitives.BytesCls) { + return result as bytes + } + throw new internal.errors.InternalError('invalid scratch slot type') +} + export const Scratch: internal.opTypes.ScratchType = { loadBytes: function (a: internal.primitives.StubUint64Compat): bytes { const result = lazyContext.activeGroup.activeTransaction.getScratchSlot(a) if (result instanceof internal.primitives.BytesCls) { return result as bytes } - throw new internal.errors.InternalError('Invalid scratch slot type') + throw new internal.errors.InternalError('invalid scratch slot type') }, loadUint64: function (a: internal.primitives.StubUint64Compat): uint64 { const result = lazyContext.activeGroup.activeTransaction.getScratchSlot(a) if (result instanceof internal.primitives.Uint64Cls) { return result as uint64 } - throw new internal.errors.InternalError('Invalid scratch slot type') + throw new internal.errors.InternalError('invalid scratch slot type') }, store: function ( a: internal.primitives.StubUint64Compat, diff --git a/src/impl/txn.ts b/src/impl/txn.ts index cd21e5f..172224f 100644 --- a/src/impl/txn.ts +++ b/src/impl/txn.ts @@ -1,19 +1,10 @@ import { Account, Application, arc4, Asset, bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asNumber, asUint64, asUint64Cls } from '../util' -// import { -// getApplicationTransaction, -// getAssetConfigTransaction, -// getAssetFreezeTransaction, -// getAssetTransferTransaction, -// getKeyRegistrationTransaction, -// getPaymentTransaction, -// getTransaction, -// } from './gtxn' export const gaid = (a: internal.primitives.StubUint64Compat): uint64 => { const group = lazyContext.activeGroup - const transaction = group.transactions[asNumber(a)] + const transaction = group.getTransaction(a) if (transaction.type === TransactionType.ApplicationCall) { return transaction.createdApp.id } else if (transaction.type === TransactionType.AssetConfig) { diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index 20f9ce5..a23e55d 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -7,6 +7,11 @@ import { AssetData } from '../impl/asset' import { GlobalData } from '../impl/global' import { asBigInt, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' +interface BlockData { + seed: bigint + timestamp: bigint +} + export class LedgerContext { appIdIter = iterBigInt(1001n, MAX_UINT64) assetIdIter = iterBigInt(1001n, MAX_UINT64) @@ -14,6 +19,7 @@ export class LedgerContext { appIdContractMap = new Map() accountDataMap = new AccountMap() assetDataMap = new Map() + blocks = new Map() globalData = new GlobalData() addAppIdContractMap(appId: internal.primitives.StubUint64Compat, contract: BaseContract): void { @@ -76,4 +82,24 @@ export class LedgerContext { ...data, } } + + setBlock( + index: internal.primitives.StubUint64Compat, + seed: internal.primitives.StubUint64Compat, + timestamp: internal.primitives.StubUint64Compat, + ): void { + const i = asBigInt(index) + const s = asBigInt(seed) + const t = asBigInt(timestamp) + + this.blocks.set(i, { seed: s, timestamp: t }) + } + + getBlockContent(index: internal.primitives.StubUint64Compat): BlockData { + const i = asBigInt(index) + if (this.blocks.has(i)) { + return this.blocks.get(i)! + } + throw internal.errors.internalError(`Block ${i} not set`) + } } diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 3be0b43..6b8a104 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -32,6 +32,7 @@ import { INITIAL_BALANCE_MICRO_ALGOS, } from './avm-invoker' import { asUint8Array } from './util' +import { Block, gloadBytes, gloadUint64 } from '../src/impl' describe('State op codes', async () => { const ctx = new TestExecutionContext() @@ -376,4 +377,65 @@ describe('State op codes', async () => { expect(() => ctx.txn.lastGroup.getScratchSlot(256)).toThrow('invalid scratch slot') }) }) + + describe('gloadBytes', async () => { + it('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) + expect(slot1).toStrictEqual('hello') + expect(slot2).toStrictEqual('world') + }) + }) + it('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 () => { + ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: [Uint64(0), Bytes('hello'), Bytes('world')] })]).execute(() => { + expect(() => gloadBytes(0, 256)).toThrow('invalid scratch slot') + }) + }) + }) + + describe('gloadUint64', async () => { + it('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) + expect(slot0).toStrictEqual(7n) + expect(slot1).toStrictEqual(42n) + }) + }) + it('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 () => { + ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: [Uint64(7), Uint64(42), Bytes('world')] })]).execute(() => { + expect(() => gloadUint64(0, 256)).toThrow('invalid scratch slot') + }) + }) + }) + + describe('Block', async () => { + it('should return the correct field value of the block', async () => { + const index = 42 + const seed = 123 + const timestamp = 1234567890 + ctx.ledger.setBlock(index, seed, timestamp) + const seedResult = op.btoi(Block.blkSeed(Uint64(index))) + const timestampResult = Block.blkTimestamp(Uint64(index)) + + expect(seedResult).toEqual(Uint64(seed)) + expect(timestampResult).toEqual(Uint64(timestamp)) + }) + it('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') + }) + }) }) From 228d2cb06a4ac0f73b546825d12d8d6f8d5f23bf Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 17 Oct 2024 10:20:17 +0800 Subject: [PATCH 26/85] use Record instead of array type to setup scratch space in tests to simplify the setup --- src/impl/scratch.ts | 4 ++-- src/impl/transactions.ts | 4 ++-- tests/state-op-codes.spec.ts | 5 +---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/impl/scratch.ts b/src/impl/scratch.ts index fb1ded7..facfb9a 100644 --- a/src/impl/scratch.ts +++ b/src/impl/scratch.ts @@ -8,7 +8,7 @@ export const gloadUint64: internal.opTypes.GloadUint64Type = ( const txn = lazyContext.activeGroup.getTransaction(a) const result = txn.getScratchSlot(b) if (result instanceof internal.primitives.Uint64Cls) { - return result as uint64 + return result.asAlgoTs() } throw new internal.errors.InternalError('invalid scratch slot type') } @@ -20,7 +20,7 @@ export const gloadBytes: internal.opTypes.GloadBytesType = ( const txn = lazyContext.activeGroup.getTransaction(a) const result = txn.getScratchSlot(b) if (result instanceof internal.primitives.BytesCls) { - return result as bytes + return result.asAlgoTs() } throw new internal.errors.InternalError('invalid scratch slot type') } diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index f0b23ae..d6fae1a 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -233,7 +233,7 @@ export type ApplicationTransactionFields = TxnFields & approvalProgramPages: Array clearStateProgramPages: Array appLogs: Array - scratchSpace: Array + scratchSpace: Record }> export class ApplicationTransaction extends TransactionBase implements gtxn.ApplicationTxn { @@ -266,7 +266,7 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl this.#apps = fields.apps ?? [] this.#approvalProgramPages = fields.approvalProgramPages ?? (fields.approvalProgram ? [fields.approvalProgram] : []) this.#clearStateProgramPages = fields.clearStateProgramPages ?? (fields.clearStateProgram ? [fields.clearStateProgram] : []) - fields.scratchSpace?.forEach((v, i) => this.setScratchSlot(i, v)) + Object.entries(fields.scratchSpace ?? {}).forEach(([k, v]) => this.setScratchSlot(Number(k), v)) } readonly appId: Application diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 6b8a104..72e9471 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -367,10 +367,7 @@ describe('State op codes', async () => { [3, Uint64(42)], [255, Bytes('max_index')], ])('should return the correct field value of the scratch slot', async (index: number, value: bytes | uint64) => { - const newScratchSpace = Array(256).fill(Uint64(0)) - newScratchSpace[index] = value - - ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: newScratchSpace })]).execute(() => {}) + ctx.txn.createScope([ctx.any.txn.applicationCall({ scratchSpace: { [index]: value } })]).execute(() => {}) expect(ctx.txn.lastGroup.getScratchSlot(index)).toEqual(value) From cd78814179c0231ba2da512e690842b5d9aee0d2 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Wed, 16 Oct 2024 09:39:48 +0800 Subject: [PATCH 27/85] feat: implement AppGlobal and add tests for it - Contract proxy returns original value without wrapping for all entries which are not ABI methods in an arc4 contract - allow invocation of contract methods which return void --- .editorconfig | 9 + .gitattributes | 6 + .vscode/settings.json | 20 ++ src/collections/custom-key-map.ts | 12 +- src/impl/app-global.ts | 50 +++ src/impl/application.ts | 11 +- src/impl/index.ts | 5 +- src/subcontexts/contract-context.ts | 42 ++- src/subcontexts/ledger-context.ts | 34 +- src/test-execution-context.ts | 3 - src/util.ts | 4 +- tests/artifacts/state-ops/contract.algo.ts | 52 +++ .../data/StateAppGlobalContract.approval.teal | 310 ++++++++++++++++++ .../data/StateAppGlobalContract.arc32.json | 188 +++++++++++ .../data/StateAppGlobalContract.clear.teal | 7 + .../StateAppGlobalExContract.approval.teal | 77 +++++ .../data/StateAppGlobalExContract.arc32.json | 60 ++++ .../data/StateAppGlobalExContract.clear.teal | 7 + tests/avm-invoker.ts | 12 +- tests/state-op-codes.spec.ts | 62 ++++ 20 files changed, 937 insertions(+), 34 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .vscode/settings.json create mode 100644 src/impl/app-global.ts create mode 100644 tests/artifacts/state-ops/data/StateAppGlobalContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/StateAppGlobalContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/StateAppGlobalContract.clear.teal create mode 100644 tests/artifacts/state-ops/data/StateAppGlobalExContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/StateAppGlobalExContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/StateAppGlobalExContract.clear.teal diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a83b72c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +[*] +charset = utf-8 +insert_final_newline = true +end_of_line = lf +indent_style = space +indent_size = 2 +tab_width = 2 +max_line_length = 140 +trim_trailing_whitespace = true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ffa574 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +# Set the repository to show as TypeScript rather than JS in GitHub +*.js linguist-detectable=false + +# Treat text as lf +* text=auto +* eol=lf diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..25d6dc2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "explicit" + }, + "eslint.validate": ["typescript"], + "eslint.options": { + "extensions": [".ts"] + }, + "typescript.preferences.quoteStyle": "single", + "yaml.schemas": { + "https://json.schemastore.org/github-workflow.json": "/.github/workflows/*.yml", + "https://json.schemastore.org/github-action.json": "/.github/actions/**/*.yml" + }, + "files.associations": { + "*.mdx": "markdown" + } +} diff --git a/src/collections/custom-key-map.ts b/src/collections/custom-key-map.ts index 709290e..b156dbb 100644 --- a/src/collections/custom-key-map.ts +++ b/src/collections/custom-key-map.ts @@ -1,6 +1,6 @@ -import { Account, internal } from '@algorandfoundation/algorand-typescript' -import { encodingUtil } from '@algorandfoundation/puya-ts' +import { Account, bytes } from '@algorandfoundation/algorand-typescript' import { DeliberateAny } from '../typescript-helpers' +import { asBytesCls } from '../util' type Primitive = number | bigint | string | boolean export abstract class CustomKeyMap implements Map { @@ -62,6 +62,12 @@ export class AccountMap extends CustomKeyMap { } private static getAddressStrFromAccount = (acc: Account) => { - return encodingUtil.uint8ArrayToHex(internal.primitives.BytesCls.fromCompat(acc.bytes).asUint8Array()) + return asBytesCls(acc.bytes).valueOf() + } +} + +export class BytesMap extends CustomKeyMap { + constructor() { + super((bytes) => asBytesCls(bytes).valueOf()) } } diff --git a/src/impl/app-global.ts b/src/impl/app-global.ts new file mode 100644 index 0000000..b97665c --- /dev/null +++ b/src/impl/app-global.ts @@ -0,0 +1,50 @@ +import { Application, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' +import { asBytes } from '../util' +import { getApp } from './app-params' + +export const AppGlobal: internal.opTypes.AppGlobalType = { + delete: function (a: internal.primitives.StubBytesCompat): void { + lazyContext.ledger.setGlobalState(lazyContext.activeApplication, a, undefined) + }, + getBytes: function (a: internal.primitives.StubBytesCompat): bytes { + return this.getExBytes(0, asBytes(a))[0] + }, + getUint64: function (a: internal.primitives.StubBytesCompat): uint64 { + return this.getExUint64(0, asBytes(a))[0] + }, + getExBytes: function ( + a: Application | internal.primitives.StubUint64Compat, + b: internal.primitives.StubBytesCompat, + ): readonly [bytes, boolean] { + const app = getApp(a) + if (app === undefined) { + return [Bytes(), false] + } + const [state, exists] = lazyContext.ledger.getGlobalState(app, b) + if (!exists) { + return [Bytes(), false] + } + return [state!.value as bytes, exists] + }, + getExUint64: function ( + a: Application | internal.primitives.StubUint64Compat, + b: internal.primitives.StubBytesCompat, + ): readonly [uint64, boolean] { + const app = getApp(a) + if (app === undefined) { + return [Uint64(0), false] + } + const [state, exists] = lazyContext.ledger.getGlobalState(app, b) + if (!exists) { + return [Uint64(0), false] + } + return [state!.value as uint64, exists] + }, + put: function ( + a: internal.primitives.StubBytesCompat, + b: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, + ): void { + lazyContext.ledger.setGlobalState(lazyContext.activeApplication, a, b) + }, +} diff --git a/src/impl/application.ts b/src/impl/application.ts index b77ab45..4abca36 100644 --- a/src/impl/application.ts +++ b/src/impl/application.ts @@ -1,5 +1,6 @@ -import { Account, Application, Bytes, bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, Application, Bytes, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' +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' @@ -7,7 +8,11 @@ import { asBigInt, asUint64 } from '../util' import { Uint64BackedCls } from './base' export class ApplicationData { - application: Mutable> & { appLogs: bytes[] } + application: Mutable> & { + appLogs: bytes[] + globalStates: BytesMap> + localStates: BytesMap> + } isCreating: boolean = false get appLogs() { @@ -25,6 +30,8 @@ export class ApplicationData { extraProgramPages: 0, creator: lazyContext.defaultSender, appLogs: [], + globalStates: new BytesMap(), + localStates: new BytesMap(), } } } diff --git a/src/impl/index.ts b/src/impl/index.ts index e280392..d786050 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -1,12 +1,13 @@ export { AcctParams, balance, minBalance } from './acct-params' +export { AppGlobal } from './app-global' export { AppParams } from './app-params' export { AssetHolding } from './asset-holding' export { AssetParams } from './asset-params' export * from './crypto' export { Global } from './global' export { GTxn } from './gtxn' -export * from './pure' -export { Txn, gaid } from './txn' export { GITxn, ITxn, ITxnCreate } from './itxn' +export * from './pure' export { Scratch, gloadBytes, gloadUint64 } from './scratch' export { Block } from './block' +export { Txn, gaid } from './txn' diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 79946e0..8e91ce1 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -1,5 +1,6 @@ import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, internal } from '@algorandfoundation/algorand-typescript' import { getAbiMetadata } from '../abi-metadata' +import { BytesMap } from '../collections/custom-key-map' import { lazyContext } from '../context-helpers/internal-context' import { AccountCls } from '../impl/account' import { ApplicationCls } from '../impl/application' @@ -15,7 +16,7 @@ import { } from '../impl/transactions' import { getGenericTypeInfo } from '../runtime-helpers' import { DeliberateAny } from '../typescript-helpers' -import { extractGenericTypeArgs } from '../util' +import { asUint64Cls, extractGenericTypeArgs } from '../util' interface IConstructor { new (...args: DeliberateAny[]): T @@ -24,8 +25,8 @@ interface IConstructor { type StateTotals = Pick interface States { - globalStates: Map> - localStates: Map> + globalStates: BytesMap> + localStates: BytesMap> totals: StateTotals } @@ -38,8 +39,8 @@ const isUint64GenericType = (typeName: string | undefined) => { const extractStates = (contract: BaseContract): States => { const stateTotals = { globalNumBytes: 0, globalNumUint: 0, localNumBytes: 0, localNumUint: 0 } const states = { - globalStates: new Map>(), - localStates: new Map>(), + globalStates: new BytesMap>(), + localStates: new BytesMap>(), totals: stateTotals, } Object.entries(contract).forEach(([key, value]) => { @@ -50,7 +51,7 @@ const extractStates = (contract: BaseContract): States => { if (value.key === undefined) value.key = Bytes(key) // capture state into the context - if (isLocalState) states.localStates.set(value.key, value.map) + if (isLocalState) states.localStates.set(value.key, value) else states.globalStates.set(value.key, value) // populate state totals @@ -64,23 +65,31 @@ const extractStates = (contract: BaseContract): States => { return states } -const extractArraysFromArgs = (args: DeliberateAny[]) => { +const extractArraysFromArgs = (app: Application, args: DeliberateAny[]) => { const transactions: Transaction[] = [] const accounts: Account[] = [] - const apps: Application[] = [] + const apps: Application[] = [app] const assets: Asset[] = [] + const appArgs: bytes[] = [] + + // TODO: replace `asUint64Cls(accounts.length).toBytes().asAlgoTs()` with `arc4.Uint8(account.length).toBytes().asAlgoTs()` for (const arg of args) { if (isTransaction(arg)) { transactions.push(arg) } else if (arg instanceof AccountCls) { + appArgs.push(asUint64Cls(accounts.length).toBytes().asAlgoTs()) accounts.push(arg as Account) } else if (arg instanceof ApplicationCls) { + appArgs.push(asUint64Cls(apps.length).toBytes().asAlgoTs()) apps.push(arg as Application) } else if (arg instanceof AssetCls) { + appArgs.push(asUint64Cls(assets.length).toBytes().asAlgoTs()) assets.push(arg as Asset) } } - return { accounts, apps, assets, transactions } + + // TODO: use actual method selector in appArgs + return { accounts, apps, assets, transactions, appArgs: [Bytes('method_selector'), ...appArgs] } } function isTransaction(obj: unknown): obj is Transaction { @@ -96,7 +105,6 @@ function isTransaction(obj: unknown): obj is Transaction { export class ContractContext { create(type: IConstructor, ...args: DeliberateAny[]): T { - Object.getPrototypeOf(type) const proxy = new Proxy(type, this.getContractProxyHandler(this.isArc4(type))) return new proxy(...args) } @@ -114,10 +122,12 @@ export class ContractContext { } private getContractProxyHandler(isArc4: boolean): ProxyHandler> { - const onConstructed = (instance: BaseContract) => { + const onConstructed = (instance: T) => { const states = extractStates(instance) const application = lazyContext.any.application({ + globalStates: states.globalStates, + localStates: states.localStates, ...states.totals, }) lazyContext.ledger.addAppIdContractMap(application.id, instance) @@ -127,12 +137,13 @@ export class ContractContext { const instance = new Proxy(new target(...args), { get(target, prop, receiver) { const orig = Reflect.get(target, prop, receiver) + const abiMetadata = getAbiMetadata(target, prop as string) const isProgramMethod = prop === 'approvalProgram' || prop === 'clearStateProgram' - if (isArc4 || isProgramMethod) { + const isAbiMethod = isArc4 && abiMetadata + if (isAbiMethod || isProgramMethod) { return (...args: DeliberateAny[]): DeliberateAny => { const app = lazyContext.ledger.getApplicationForContract(receiver) - const { transactions, ...appCallArgs } = extractArraysFromArgs(args) - const abiMetadata = getAbiMetadata(target, prop as string) + const { transactions, ...appCallArgs } = extractArraysFromArgs(app, args) const appTxn = lazyContext.any.txn.applicationCall({ appId: app, ...appCallArgs, @@ -142,7 +153,7 @@ export class ContractContext { const txns = [...(transactions ?? []), appTxn] return lazyContext.txn.ensureScope(txns).execute(() => { const returnValue = (orig as DeliberateAny).apply(target, args) - if (!isProgramMethod && isArc4 && returnValue !== undefined) { + if (!isProgramMethod && isAbiMethod && returnValue !== undefined) { appTxn.logArc4ReturnValue(returnValue) } return returnValue @@ -152,6 +163,7 @@ export class ContractContext { return orig }, }) + onConstructed(instance) return instance diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index a23e55d..33f1694 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -5,7 +5,7 @@ import { AccountData, AssetHolding } from '../impl/account' import { ApplicationData } from '../impl/application' import { AssetData } from '../impl/asset' import { GlobalData } from '../impl/global' -import { asBigInt, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' +import { asBigInt, asBytes, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' interface BlockData { seed: bigint @@ -102,4 +102,36 @@ export class LedgerContext { } throw internal.errors.internalError(`Block ${i} not set`) } + + getGlobalState( + app: Application, + key: internal.primitives.StubBytesCompat, + ): [internal.state.GlobalStateCls | undefined, boolean] { + const appId = asBigInt(app.id) + const keyBytes = asBytes(key) + if (!this.applicationDataMap.has(appId)) { + return [undefined, false] + } + const appData = this.applicationDataMap.get(appId)! + if (!appData.application.globalStates.has(keyBytes)) { + return [undefined, false] + } + return [appData.application.globalStates.get(keyBytes), true] + } + + setGlobalState( + app: Application, + key: internal.primitives.StubBytesCompat, + value: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat | undefined, + ): void { + const appId = asBigInt(app.id) + const keyBytes = asBytes(key) + const appData = this.applicationDataMap.get(appId)! + const globalState = appData.application.globalStates.get(keyBytes)! + if (value === undefined) { + globalState.delete() + } else { + globalState.value = asMaybeUint64Cls(value) ?? asMaybeBytesCls(value) + } + } } diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 9653a53..73415d0 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -21,7 +21,6 @@ import { TransactionContext } from './subcontexts/transaction-context' import { ValueGenerator } from './value-generators' export class TestExecutionContext implements internal.ExecutionContext { - #applicationLogs: Map #contractContext: ContractContext #ledgerContext: LedgerContext #txnContext: TransactionContext @@ -30,7 +29,6 @@ export class TestExecutionContext implements internal.ExecutionContext { constructor() { internal.ctxMgr.instance = this - this.#applicationLogs = new Map() this.#contractContext = new ContractContext() this.#ledgerContext = new LedgerContext() this.#txnContext = new TransactionContext() @@ -112,7 +110,6 @@ export class TestExecutionContext implements internal.ExecutionContext { } reset() { - this.#applicationLogs.clear() this.#contractContext = new ContractContext() this.#ledgerContext = new LedgerContext() this.#txnContext = new TransactionContext() diff --git a/src/util.ts b/src/util.ts index 8c5835d..03d5fc6 100644 --- a/src/util.ts +++ b/src/util.ts @@ -68,7 +68,9 @@ export const toBytes = (val: unknown): bytes => { return val.reduce((acc: bytes, cur: unknown) => { const uint64Val = asMaybeUint64Cls(cur) if (!uint64Val) { - internal.errors.internalError(`ABI tuple encoding not supported: ${nameOfType(val)}`) + // TODO: support ABI tuple encoding + // internal.errors.internalError(`ABI tuple encoding not supported: ${nameOfType(val)}`) + return acc.concat(Bytes()) } return acc.concat(toBytes(cur)) }, Bytes()) diff --git a/tests/artifacts/state-ops/contract.algo.ts b/tests/artifacts/state-ops/contract.algo.ts index 5363c82..0b29457 100644 --- a/tests/artifacts/state-ops/contract.algo.ts +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -353,6 +353,58 @@ export class StateAppParamsContract extends arc4.Contract { } } +export class StateAppGlobalExContract extends arc4.Contract { + globalUint64 = GlobalState({ key: Bytes('global_uint64'), initialValue: Uint64(2) }) + globalBytes = GlobalState({ key: Bytes('global_bytes'), initialValue: Bytes('dummy_bytes') }) + global_uint64_explicit = GlobalState({ initialValue: Uint64(2) }) + global_bytes_explicit = GlobalState({ initialValue: Bytes('dummy_bytes') }) + // TODO: uncomment when arc4 types are ready + // globalArc4Bytes = GlobalState({ key: Bytes('global_arc4_bytes'), initialValue: arc4.DynamicBytes('dummy_arc4_bytes') }) + // global_arc4_bytes_explicit = GlobalState({ initialValue: arc4.DynamicBytes('dummy_arc4_bytes') }) +} + +export class StateAppGlobalContract extends arc4.Contract { + globalUint64 = GlobalState({ key: Bytes('global_uint64') }) + globalBytes = GlobalState({ key: Bytes('global_bytes') }) + + @arc4.abimethod() + verify_get_bytes(a: bytes): bytes { + const value = op.AppGlobal.getBytes(a) + return value + } + + @arc4.abimethod() + verify_get_uint64(a: bytes): uint64 { + const value = op.AppGlobal.getUint64(a) + return value + } + + @arc4.abimethod() + verify_get_ex_bytes(a: Application, b: bytes): readonly [bytes, boolean] { + return op.AppGlobal.getExBytes(a, b) + } + + @arc4.abimethod() + verify_get_ex_uint64(a: Application, b: bytes): readonly [uint64, boolean] { + return op.AppGlobal.getExUint64(a, b) + } + + @arc4.abimethod() + verify_put_uint64(a: bytes, b: uint64): void { + op.AppGlobal.put(a, b) + } + + @arc4.abimethod() + verify_put_bytes(a: bytes, b: bytes): void { + op.AppGlobal.put(a, b) + } + + @arc4.abimethod() + verify_delete(a: bytes): void { + op.AppGlobal.delete(a) + } +} + export class ITxnOpsContract extends arc4.Contract { @arc4.abimethod() public verify_itxn_ops() { diff --git a/tests/artifacts/state-ops/data/StateAppGlobalContract.approval.teal b/tests/artifacts/state-ops/data/StateAppGlobalContract.approval.teal new file mode 100644 index 0000000..8dfab14 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppGlobalContract.approval.teal @@ -0,0 +1,310 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAppGlobalContract.approval_program: + // tests/artifacts/StateOps/contract.py:422 + // class StateAppGlobalContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@11 + 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_delete(byte[])void" + method "verify_put_uint64(byte[],uint64)void" + method "verify_put_bytes(byte[],byte[])void" + txna ApplicationArgs 0 + match main_verify_get_bytes_route@2 main_verify_get_uint64_route@3 main_verify_get_ex_bytes_route@4 main_verify_get_ex_uint64_route@5 main_verify_delete_route@6 main_verify_put_uint64_route@7 main_verify_put_bytes_route@8 + err // reject transaction + +main_verify_get_bytes_route@2: + // tests/artifacts/StateOps/contract.py:434 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:422 + // class StateAppGlobalContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/StateOps/contract.py:434 + // @arc4.abimethod() + callsub verify_get_bytes + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_get_uint64_route@3: + // tests/artifacts/StateOps/contract.py:439 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:422 + // class StateAppGlobalContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/StateOps/contract.py:439 + // @arc4.abimethod() + callsub verify_get_uint64 + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_get_ex_bytes_route@4: + // tests/artifacts/StateOps/contract.py:444 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:422 + // class StateAppGlobalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/StateOps/contract.py:444 + // @arc4.abimethod() + callsub verify_get_ex_bytes + swap + dup + len + itob + extract 6 2 + swap + concat + byte 0x00 + int 0 + uncover 3 + setbit + byte 0x0003 + swap + concat + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_get_ex_uint64_route@5: + // tests/artifacts/StateOps/contract.py:448 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:422 + // class StateAppGlobalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Applications + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/StateOps/contract.py:448 + // @arc4.abimethod() + callsub verify_get_ex_uint64 + swap + itob + byte 0x00 + int 0 + uncover 3 + setbit + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_delete_route@6: + // tests/artifacts/StateOps/contract.py:452 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:422 + // class StateAppGlobalContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + // tests/artifacts/StateOps/contract.py:452 + // @arc4.abimethod() + callsub verify_delete + int 1 + return + +main_verify_put_uint64_route@7: + // tests/artifacts/StateOps/contract.py:456 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:422 + // class StateAppGlobalContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + btoi + // tests/artifacts/StateOps/contract.py:456 + // @arc4.abimethod() + callsub verify_put_uint64 + int 1 + return + +main_verify_put_bytes_route@8: + // tests/artifacts/StateOps/contract.py:460 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:422 + // class StateAppGlobalContract(ARC4Contract): + txna ApplicationArgs 1 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/StateOps/contract.py:460 + // @arc4.abimethod() + callsub verify_put_bytes + int 1 + return + +main_bare_routing@11: + // tests/artifacts/StateOps/contract.py:422 + // class StateAppGlobalContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_get_bytes(a: bytes) -> bytes: +verify_get_bytes: + // tests/artifacts/StateOps/contract.py:434-435 + // @arc4.abimethod() + // def verify_get_bytes(self, a: Bytes) -> Bytes: + proto 1 1 + // tests/artifacts/StateOps/contract.py:436 + // value = op.AppGlobal.get_bytes(a) + frame_dig -1 + app_global_get + // tests/artifacts/StateOps/contract.py:437 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_get_uint64(a: bytes) -> uint64: +verify_get_uint64: + // tests/artifacts/StateOps/contract.py:439-440 + // @arc4.abimethod() + // def verify_get_uint64(self, a: Bytes) -> UInt64: + proto 1 1 + // tests/artifacts/StateOps/contract.py:441 + // value = op.AppGlobal.get_uint64(a) + frame_dig -1 + app_global_get + // tests/artifacts/StateOps/contract.py:442 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_get_ex_bytes(a: uint64, b: bytes) -> bytes, uint64: +verify_get_ex_bytes: + // tests/artifacts/StateOps/contract.py:444-445 + // @arc4.abimethod() + // def verify_get_ex_bytes(self, a: Application, b: Bytes) -> tuple[Bytes, bool]: + proto 2 2 + // tests/artifacts/StateOps/contract.py:446 + // return op.AppGlobal.get_ex_bytes(a, b) + frame_dig -2 + frame_dig -1 + app_global_get_ex + retsub + + +// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_get_ex_uint64(a: uint64, b: bytes) -> uint64, uint64: +verify_get_ex_uint64: + // tests/artifacts/StateOps/contract.py:448-449 + // @arc4.abimethod() + // def verify_get_ex_uint64(self, a: Application, b: Bytes) -> tuple[UInt64, bool]: + proto 2 2 + // tests/artifacts/StateOps/contract.py:450 + // return op.AppGlobal.get_ex_uint64(a, b) + frame_dig -2 + frame_dig -1 + app_global_get_ex + retsub + + +// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_delete(a: bytes) -> void: +verify_delete: + // tests/artifacts/StateOps/contract.py:452-453 + // @arc4.abimethod() + // def verify_delete(self, a: Bytes) -> None: + proto 1 0 + // tests/artifacts/StateOps/contract.py:454 + // op.AppGlobal.delete(a) + frame_dig -1 + app_global_del + retsub + + +// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_put_uint64(a: bytes, b: uint64) -> void: +verify_put_uint64: + // tests/artifacts/StateOps/contract.py:456-457 + // @arc4.abimethod() + // def verify_put_uint64(self, a: Bytes, b: UInt64) -> None: + proto 2 0 + // tests/artifacts/StateOps/contract.py:458 + // op.AppGlobal.put(a, b) + frame_dig -2 + frame_dig -1 + app_global_put + retsub + + +// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_put_bytes(a: bytes, b: bytes) -> void: +verify_put_bytes: + // tests/artifacts/StateOps/contract.py:460-461 + // @arc4.abimethod() + // def verify_put_bytes(self, a: Bytes, b: Bytes) -> None: + proto 2 0 + // tests/artifacts/StateOps/contract.py:462 + // op.AppGlobal.put(a, b) + frame_dig -2 + frame_dig -1 + app_global_put + retsub diff --git a/tests/artifacts/state-ops/data/StateAppGlobalContract.arc32.json b/tests/artifacts/state-ops/data/StateAppGlobalContract.arc32.json new file mode 100644 index 0000000..0f891de --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppGlobalContract.arc32.json @@ -0,0 +1,188 @@ +{ + "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_delete(byte[])void": { + "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" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDExCiAgICBtZXRob2QgInZlcmlmeV9nZXRfYnl0ZXMoYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF91aW50NjQoYnl0ZVtdKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF9leF9ieXRlcyhhcHBsaWNhdGlvbixieXRlW10pKGJ5dGVbXSxib29sKSIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF9leF91aW50NjQoYXBwbGljYXRpb24sYnl0ZVtdKSh1aW50NjQsYm9vbCkiCiAgICBtZXRob2QgInZlcmlmeV9kZWxldGUoYnl0ZVtdKXZvaWQiCiAgICBtZXRob2QgInZlcmlmeV9wdXRfdWludDY0KGJ5dGVbXSx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X3B1dF9ieXRlcyhieXRlW10sYnl0ZVtdKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX3ZlcmlmeV9nZXRfYnl0ZXNfcm91dGVAMiBtYWluX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDMgbWFpbl92ZXJpZnlfZ2V0X2V4X2J5dGVzX3JvdXRlQDQgbWFpbl92ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1IG1haW5fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA2IG1haW5fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVANyBtYWluX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAOAogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfdWludDY0CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfZXhfYnl0ZXNfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDIyCiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0X2V4X2J5dGVzCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgwMDAzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjIKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfdWludDY0CiAgICBzd2FwCiAgICBpdG9iCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDMKICAgIHNldGJpdAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9kZWxldGVfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDIyCiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2RlbGV0ZQogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjIKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X3VpbnQ2NAogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfcHV0X2J5dGVzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X2J5dGVzCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0AxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjIKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfZ2V0X2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2dldF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzQtNDM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfYnl0ZXMoc2VsZiwgYTogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM2CiAgICAvLyB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRfYnl0ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X2dldF91aW50NjQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM5LTQ0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X3VpbnQ2NChzZWxmLCBhOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQxCiAgICAvLyB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRfdWludDY0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQyCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfYnl0ZXMoYTogdWludDY0LCBiOiBieXRlcykgLT4gYnl0ZXMsIHVpbnQ2NDoKdmVyaWZ5X2dldF9leF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDQtNDQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfYnl0ZXMoc2VsZiwgYTogQXBwbGljYXRpb24sIGI6IEJ5dGVzKSAtPiB0dXBsZVtCeXRlcywgYm9vbF06CiAgICBwcm90byAyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDYKICAgIC8vIHJldHVybiBvcC5BcHBHbG9iYWwuZ2V0X2V4X2J5dGVzKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfdWludDY0KGE6IHVpbnQ2NCwgYjogYnl0ZXMpIC0+IHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDgtNDQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfdWludDY0KHNlbGYsIGE6IEFwcGxpY2F0aW9uLCBiOiBCeXRlcykgLT4gdHVwbGVbVUludDY0LCBib29sXToKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1MAogICAgLy8gcmV0dXJuIG9wLkFwcEdsb2JhbC5nZXRfZXhfdWludDY0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9kZWxldGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDUyLTQ1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZGVsZXRlKHNlbGYsIGE6IEJ5dGVzKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU0CiAgICAvLyBvcC5BcHBHbG9iYWwuZGVsZXRlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZGVsCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB2b2lkOgp2ZXJpZnlfcHV0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NTYtNDU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9wdXRfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NTgKICAgIC8vIG9wLkFwcEdsb2JhbC5wdXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9wdXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYwLTQ2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfcHV0X2J5dGVzKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ2MgogICAgLy8gb3AuQXBwR2xvYmFsLnB1dChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + }, + "state": { + "global": { + "num_byte_slices": 1, + "num_uints": 1 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": { + "global_bytes": { + "type": "bytes", + "key": "global_bytes" + }, + "global_uint64": { + "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_delete", + "args": [ + { + "type": "byte[]", + "name": "a" + } + ], + "readonly": false, + "returns": { + "type": "void" + } + }, + { + "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" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ 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 new file mode 100644 index 0000000..d7a1245 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppGlobalContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAppGlobalContract.clear_state_program: + // tests/artifacts/StateOps/contract.py:422 + // class StateAppGlobalContract(ARC4Contract): + int 1 + return diff --git a/tests/artifacts/state-ops/data/StateAppGlobalExContract.approval.teal b/tests/artifacts/state-ops/data/StateAppGlobalExContract.approval.teal new file mode 100644 index 0000000..35af159 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppGlobalExContract.approval.teal @@ -0,0 +1,77 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAppGlobalExContract.approval_program: + txn ApplicationID + bnz main_entrypoint@2 + callsub __init__ + +main_entrypoint@2: + // tests/artifacts/StateOps/contract.py:404 + // class StateAppGlobalExContract(ARC4Contract): + txn NumAppArgs + ! + assert // reject transaction + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.StateOps.contract.StateAppGlobalExContract.__init__() -> void: +__init__: + // tests/artifacts/StateOps/contract.py:405 + // def __init__(self) -> None: + proto 0 0 + // tests/artifacts/StateOps/contract.py:408 + // key="global_uint64", + byte "global_uint64" + // tests/artifacts/StateOps/contract.py:407 + // UInt64(2), + int 2 + // tests/artifacts/StateOps/contract.py:406-409 + // self.global_uint64 = GlobalState( + // UInt64(2), + // key="global_uint64", + // ) + app_global_put + // tests/artifacts/StateOps/contract.py:412 + // key="global_bytes", + byte "global_bytes" + // tests/artifacts/StateOps/contract.py:411 + // Bytes(b"dummy_bytes"), + byte 0x64756d6d795f6279746573 + // tests/artifacts/StateOps/contract.py:410-413 + // self.global_bytes = GlobalState( + // Bytes(b"dummy_bytes"), + // key="global_bytes", + // ) + app_global_put + // tests/artifacts/StateOps/contract.py:414 + // self.global_uint64_explicit = algopy.UInt64(2) + byte "global_uint64_explicit" + int 2 + app_global_put + // tests/artifacts/StateOps/contract.py:415 + // self.global_bytes_explicit = algopy.Bytes(b"dummy_bytes") + byte "global_bytes_explicit" + byte 0x64756d6d795f6279746573 + app_global_put + // tests/artifacts/StateOps/contract.py:417 + // algopy.arc4.DynamicBytes(b"dummy_arc4_bytes"), key="global_arc4_bytes" + byte "global_arc4_bytes" + byte 0x001064756d6d795f617263345f6279746573 + // tests/artifacts/StateOps/contract.py:416-418 + // self.global_arc4_bytes = GlobalState( + // algopy.arc4.DynamicBytes(b"dummy_arc4_bytes"), key="global_arc4_bytes" + // ) + app_global_put + // tests/artifacts/StateOps/contract.py:419 + // self.global_arc4_bytes_explicit = algopy.arc4.DynamicBytes(b"dummy_arc4_bytes") + byte "global_arc4_bytes_explicit" + byte 0x001064756d6d795f617263345f6279746573 + app_global_put + retsub diff --git a/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc32.json b/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc32.json new file mode 100644 index 0000000..4492dbf --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc32.json @@ -0,0 +1,60 @@ +{ + "hints": {}, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDQKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsRXhDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0Ll9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA1CiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQwOAogICAgLy8ga2V5PSJnbG9iYWxfdWludDY0IiwKICAgIGJ5dGUgImdsb2JhbF91aW50NjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA3CiAgICAvLyBVSW50NjQoMiksCiAgICBpbnQgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQwNi00MDkKICAgIC8vIHNlbGYuZ2xvYmFsX3VpbnQ2NCA9IEdsb2JhbFN0YXRlKAogICAgLy8gICAgIFVJbnQ2NCgyKSwKICAgIC8vICAgICBrZXk9Imdsb2JhbF91aW50NjQiLAogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTIKICAgIC8vIGtleT0iZ2xvYmFsX2J5dGVzIiwKICAgIGJ5dGUgImdsb2JhbF9ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTEKICAgIC8vIEJ5dGVzKGIiZHVtbXlfYnl0ZXMiKSwKICAgIGJ5dGUgMHg2NDc1NmQ2ZDc5NWY2Mjc5NzQ2NTczCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDEwLTQxMwogICAgLy8gc2VsZi5nbG9iYWxfYnl0ZXMgPSBHbG9iYWxTdGF0ZSgKICAgIC8vICAgICBCeXRlcyhiImR1bW15X2J5dGVzIiksCiAgICAvLyAgICAga2V5PSJnbG9iYWxfYnl0ZXMiLAogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTQKICAgIC8vIHNlbGYuZ2xvYmFsX3VpbnQ2NF9leHBsaWNpdCA9IGFsZ29weS5VSW50NjQoMikKICAgIGJ5dGUgImdsb2JhbF91aW50NjRfZXhwbGljaXQiCiAgICBpbnQgMgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTUKICAgIC8vIHNlbGYuZ2xvYmFsX2J5dGVzX2V4cGxpY2l0ID0gYWxnb3B5LkJ5dGVzKGIiZHVtbXlfYnl0ZXMiKQogICAgYnl0ZSAiZ2xvYmFsX2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZSAweDY0NzU2ZDZkNzk1ZjYyNzk3NDY1NzMKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDE3CiAgICAvLyBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoYiJkdW1teV9hcmM0X2J5dGVzIiksIGtleT0iZ2xvYmFsX2FyYzRfYnl0ZXMiCiAgICBieXRlICJnbG9iYWxfYXJjNF9ieXRlcyIKICAgIGJ5dGUgMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTYtNDE4CiAgICAvLyBzZWxmLmdsb2JhbF9hcmM0X2J5dGVzID0gR2xvYmFsU3RhdGUoCiAgICAvLyAgICAgYWxnb3B5LmFyYzQuRHluYW1pY0J5dGVzKGIiZHVtbXlfYXJjNF9ieXRlcyIpLCBrZXk9Imdsb2JhbF9hcmM0X2J5dGVzIgogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTkKICAgIC8vIHNlbGYuZ2xvYmFsX2FyYzRfYnl0ZXNfZXhwbGljaXQgPSBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoYiJkdW1teV9hcmM0X2J5dGVzIikKICAgIGJ5dGUgImdsb2JhbF9hcmM0X2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZSAweDAwMTA2NDc1NmQ2ZDc5NWY2MTcyNjMzNDVmNjI3OTc0NjU3MwogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA0CiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + }, + "state": { + "global": { + "num_byte_slices": 4, + "num_uints": 2 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "schema": { + "global": { + "declared": { + "global_arc4_bytes": { + "type": "bytes", + "key": "global_arc4_bytes" + }, + "global_arc4_bytes_explicit": { + "type": "bytes", + "key": "global_arc4_bytes_explicit" + }, + "global_bytes": { + "type": "bytes", + "key": "global_bytes" + }, + "global_bytes_explicit": { + "type": "bytes", + "key": "global_bytes_explicit" + }, + "global_uint64": { + "type": "uint64", + "key": "global_uint64" + }, + "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.clear.teal b/tests/artifacts/state-ops/data/StateAppGlobalExContract.clear.teal new file mode 100644 index 0000000..3d0e5c8 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppGlobalExContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAppGlobalExContract.clear_state_program: + // tests/artifacts/StateOps/contract.py:404 + // class StateAppGlobalExContract(ARC4Contract): + int 1 + return diff --git a/tests/avm-invoker.ts b/tests/avm-invoker.ts index 7aa6005..edd23ae 100644 --- a/tests/avm-invoker.ts +++ b/tests/avm-invoker.ts @@ -35,12 +35,10 @@ const invokeMethod = async ( method: string, sendParams?: SendTransactionParams, ...methodArgs: ABIAppCallArg[] -): Promise => { +): Promise => { const response = await appClient.call({ method, methodArgs, note: randomUUID(), sendParams }) - if (!response.return) { - throw new Error(`${method} did not return a value`) - } - if (response.return.decodeError) { + + if (response.return?.decodeError) { throw response.return.decodeError } return response.return @@ -52,7 +50,7 @@ export const getAvmResult = async ( ...methodArgs: ABIAppCallArg[] ): Promise => { const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) - return result.returnValue as TResult + return result?.returnValue as TResult } export const getAvmResultRaw = async ( @@ -61,7 +59,7 @@ export const getAvmResultRaw = async ( ...methodArgs: ABIAppCallArg[] ): Promise => { const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) - return result.rawReturnValue + return result?.rawReturnValue } export const getLocalNetDefaultAccount = () => { diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 72e9471..27243c4 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -14,11 +14,15 @@ import { ItxnDemoContract, ITxnOpsContract, StateAcctParamsGetContract, + StateAppGlobalContract, + StateAppGlobalExContract, StateAppParamsContract, 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 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' @@ -435,4 +439,62 @@ describe('State op codes', async () => { expect(() => Block.blkTimestamp(Uint64(index))).toThrow('Block 42 not set') }) }) + + describe('AppGlobal', async () => { + const appClient = await getAlgorandAppClient(appGlobalAppSpecJson as AppSpec) + const [_exAppClient, exApp] = await getAlgorandAppClientWithApp(appGlobalExAppSpecJson as AppSpec) + it('should be able to put, get and delete app global state', async () => { + const bytesKey = 'global_bytes' + const uint64Key = 'global_uint64' + const bytesValue = 'test_bytes' + const uint64Value = 42 + + // put + await getAvmResult({ appClient }, 'verify_put_bytes', asUint8Array(bytesKey), asUint8Array(bytesValue)) + await getAvmResult({ appClient }, 'verify_put_uint64', asUint8Array(uint64Key), uint64Value) + + const contract = ctx.contract.create(StateAppGlobalContract) + contract.verify_put_bytes(Bytes(bytesKey), Bytes(bytesValue)) + contract.verify_put_uint64(Bytes(uint64Key), Uint64(uint64Value)) + + // get + const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_bytes', asUint8Array(bytesKey)) + const uint64AvmResult = await getAvmResult({ appClient }, 'verify_get_uint64', asUint8Array(uint64Key)) + + const bytesResult = contract.verify_get_bytes(Bytes(bytesKey)) + const uint64Result = contract.verify_get_uint64(Bytes(uint64Key)) + expect(bytesResult).toEqual(bytesAvmResult) + expect(asBigInt(uint64Result)).toEqual(uint64AvmResult) + + // delete + await getAvmResult({ appClient }, 'verify_delete', asUint8Array(bytesKey)) + await getAvmResult({ appClient }, 'verify_delete', asUint8Array(uint64Key)) + contract.verify_delete(Bytes(bytesKey)) + contract.verify_delete(Bytes(uint64Key)) + + await expect(() => getAvmResult({ appClient }, 'verify_get_bytes', asUint8Array(bytesKey))).rejects.toThrow() + expect(() => contract.verify_get_bytes(Bytes(bytesKey))).toThrow('value is not set') + + const uint64AvmResult2 = await getAvmResult({ appClient }, 'verify_get_uint64', asUint8Array(uint64Key)) + const uint64Result2 = contract.verify_get_uint64(Bytes(uint64Key)) + expect(asBigInt(uint64Result2)).toEqual(uint64AvmResult2) + }) + + it('should be able to use _ex methods to get state of another app', async () => { + const key = 'global_bytes_explicit' + const secondContract = ctx.contract.create(StateAppGlobalExContract) + const secondApp = ctx.ledger.getApplicationForContract(secondContract) + expect(secondApp.globalNumUint.valueOf()).toEqual(2) + expect(secondApp.globalNumBytes.valueOf()).toEqual(2) + + const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_ex_bytes', exApp.appId, asUint8Array(key)) + + const contract = ctx.contract.create(StateAppGlobalContract) + const bytesResult = contract.verify_get_ex_bytes(secondApp, Bytes(key)) + + expect(bytesResult).toEqual(bytesAvmResult) + }) + + // TODO: implement test_app_global_ex_get_arc4 test method when arc4 stubs are implemented + }) }) From b3499059a5998ecc0d234d4509f5af49be6781ce Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 17 Oct 2024 11:54:48 +0800 Subject: [PATCH 28/85] refactor: use custom key map to reduce type casting and add getOrFail method to enforce non null return value --- src/collections/custom-key-map.ts | 19 ++++++++-- src/context-helpers/internal-context.ts | 3 +- src/impl/account.ts | 7 ++-- src/impl/asset-holding.ts | 3 +- src/impl/asset.ts | 7 ++-- src/subcontexts/ledger-context.ts | 49 ++++++++++--------------- src/value-generators/avm.ts | 8 ++-- src/value-generators/txn.ts | 3 +- 8 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/collections/custom-key-map.ts b/src/collections/custom-key-map.ts index b156dbb..fe6043f 100644 --- a/src/collections/custom-key-map.ts +++ b/src/collections/custom-key-map.ts @@ -1,6 +1,6 @@ -import { Account, bytes } from '@algorandfoundation/algorand-typescript' +import { Account, internal } from '@algorandfoundation/algorand-typescript' import { DeliberateAny } from '../typescript-helpers' -import { asBytesCls } from '../util' +import { asBytesCls, asUint64Cls } from '../util' type Primitive = number | bigint | string | boolean export abstract class CustomKeyMap implements Map { @@ -25,6 +25,13 @@ export abstract class CustomKeyMap implements Map { get(key: TKey): TValue | undefined { return this.#map.get(this.#keySerializer(key))?.[1] } + getOrFail(key: TKey): TValue { + const value = this.get(key) + if (value === undefined) { + throw internal.errors.internalError('Key not found') + } + return value + } has(key: TKey): boolean { return this.#map.has(this.#keySerializer(key)) } @@ -66,8 +73,14 @@ 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 { + constructor() { + super((uint64) => asUint64Cls(uint64).valueOf()) + } +} diff --git a/src/context-helpers/internal-context.ts b/src/context-helpers/internal-context.ts index 0a27c2c..459e995 100644 --- a/src/context-helpers/internal-context.ts +++ b/src/context-helpers/internal-context.ts @@ -61,8 +61,7 @@ class InternalContext { } getApplicationData(id: internal.primitives.StubUint64Compat): ApplicationData { - const key = internal.primitives.Uint64Cls.fromCompat(id) - const data = this.ledger.applicationDataMap.get(key.asBigInt()) + const data = this.ledger.applicationDataMap.get(id) if (!data) { throw internal.errors.internalError('Unknown application, check correct testing context is active') } diff --git a/src/impl/account.ts b/src/impl/account.ts index f803125..0f5f67d 100644 --- a/src/impl/account.ts +++ b/src/impl/account.ts @@ -1,4 +1,5 @@ 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' @@ -17,8 +18,8 @@ export class AssetHolding { } export class AccountData { - optedAssets = new Map() - optedApplications = new Map() + optedAssets = new Uint64Map() + optedApplications = new Uint64Map() account: Mutable> constructor() { @@ -91,7 +92,7 @@ export class AccountCls extends BytesBackedCls implements Account { isOptedIn(assetOrApp: Asset | Application): boolean { if (assetOrApp instanceof AssetCls) { - return this.data.optedAssets.has(asUint64Cls(assetOrApp.id).asBigInt()) + return this.data.optedAssets.has(assetOrApp.id) } if (assetOrApp instanceof ApplicationCls) { return this.data.optedApplications.has(asUint64Cls(assetOrApp.id).asBigInt()) diff --git a/src/impl/asset-holding.ts b/src/impl/asset-holding.ts index b25bb9b..c5bb593 100644 --- a/src/impl/asset-holding.ts +++ b/src/impl/asset-holding.ts @@ -1,6 +1,5 @@ import { Account, Asset, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { asBigInt } from '../util' import { AssetHolding as AssetHoldingData } from './account' import { getAccount } from './acct-params' import { getAsset } from './asset-params' @@ -16,7 +15,7 @@ const getAssetHolding = ( } const accountData = lazyContext.getAccountData(account) - const holding = accountData.optedAssets.get(asBigInt(asset.id)) + const holding = accountData.optedAssets.get(asset.id) if (holding === undefined) { return undefined } diff --git a/src/impl/asset.ts b/src/impl/asset.ts index bc34ace..5eeb156 100644 --- a/src/impl/asset.ts +++ b/src/impl/asset.ts @@ -1,7 +1,7 @@ import { Account, Asset, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { Mutable } from '../typescript-helpers' -import { asBigInt, asUint64 } from '../util' +import { asUint64 } from '../util' import { AssetHolding } from './account' import { Uint64BackedCls } from './base' @@ -65,11 +65,12 @@ export class AssetCls extends Uint64BackedCls implements Asset { private getAssetHolding(account: Account): AssetHolding { const accountData = lazyContext.getAccountData(account) - if (!accountData.optedAssets.has(asBigInt(this.id))) { + 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 accountData.optedAssets.get(asBigInt(this.id))! + return assetHolding } } diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index 33f1694..d6d158e 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -1,11 +1,12 @@ import { Account, Application, Asset, BaseContract, internal } from '@algorandfoundation/algorand-typescript' -import { AccountMap } from '../collections/custom-key-map' +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 { GlobalData } from '../impl/global' -import { asBigInt, asBytes, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' +import { GlobalStateCls } from '../impl/state' +import { asBigInt, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' interface BlockData { seed: bigint @@ -15,29 +16,27 @@ interface BlockData { export class LedgerContext { appIdIter = iterBigInt(1001n, MAX_UINT64) assetIdIter = iterBigInt(1001n, MAX_UINT64) - applicationDataMap = new Map() - appIdContractMap = new Map() + applicationDataMap = new Uint64Map() + appIdContractMap = new Uint64Map() accountDataMap = new AccountMap() - assetDataMap = new Map() - blocks = new Map() + assetDataMap = new Uint64Map() + blocks = new Uint64Map() globalData = new GlobalData() addAppIdContractMap(appId: internal.primitives.StubUint64Compat, contract: BaseContract): void { - this.appIdContractMap.set(asBigInt(appId), contract) + this.appIdContractMap.set(appId, contract) } getAsset(assetId: internal.primitives.StubUint64Compat): Asset { - const id = asBigInt(assetId) - if (this.assetDataMap.has(id)) { - return Asset(asUint64(id)) + if (this.assetDataMap.has(assetId)) { + return Asset(asUint64(assetId)) } throw internal.errors.internalError('Unknown asset, check correct testing context is active') } getApplication(applicationId: internal.primitives.StubUint64Compat): Application { - const id = asBigInt(applicationId) - if (this.applicationDataMap.has(id)) { - return Application(asUint64(id)) + if (this.applicationDataMap.has(applicationId)) { + return Application(asUint64(applicationId)) } throw internal.errors.internalError('Unknown application, check correct testing context is active') } @@ -67,7 +66,7 @@ export class LedgerContext { balance?: internal.primitives.StubUint64Compat, frozen?: boolean, ): void { - const id = (asMaybeUint64Cls(assetId) ?? asUint64Cls((assetId as Asset).id)).asBigInt() + const id = asMaybeUint64Cls(assetId) ?? asUint64Cls((assetId as Asset).id) const accountData = this.accountDataMap.get(account)! const asset = this.assetDataMap.get(id)! const holding = accountData.optedAssets.get(id) ?? new AssetHolding(0n, asset.defaultFrozen) @@ -103,20 +102,12 @@ export class LedgerContext { throw internal.errors.internalError(`Block ${i} not set`) } - getGlobalState( - app: Application, - key: internal.primitives.StubBytesCompat, - ): [internal.state.GlobalStateCls | undefined, boolean] { - const appId = asBigInt(app.id) - const keyBytes = asBytes(key) - if (!this.applicationDataMap.has(appId)) { - return [undefined, false] - } - const appData = this.applicationDataMap.get(appId)! - if (!appData.application.globalStates.has(keyBytes)) { + getGlobalState(app: Application, key: internal.primitives.StubBytesCompat): [GlobalStateCls, true] | [undefined, false] { + const appData = this.applicationDataMap.get(app.id) + if (!appData?.application.globalStates.has(key)) { return [undefined, false] } - return [appData.application.globalStates.get(keyBytes), true] + return [appData.application.globalStates.getOrFail(key), true] } setGlobalState( @@ -124,10 +115,8 @@ export class LedgerContext { key: internal.primitives.StubBytesCompat, value: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat | undefined, ): void { - const appId = asBigInt(app.id) - const keyBytes = asBytes(key) - const appData = this.applicationDataMap.get(appId)! - const globalState = appData.application.globalStates.get(keyBytes)! + const appData = this.applicationDataMap.getOrFail(app.id) + const globalState = appData.application.globalStates.getOrFail(key) if (value === undefined) { globalState.delete() } else { diff --git a/src/value-generators/avm.ts b/src/value-generators/avm.ts index d7ab239..b328f01 100644 --- a/src/value-generators/avm.ts +++ b/src/value-generators/avm.ts @@ -68,7 +68,7 @@ export class AvmValueGenerator { asset(input?: AssetContextData): Asset { const id = input?.assetId - if (id && lazyContext.ledger.assetDataMap.has(asBigInt(id))) { + if (id && lazyContext.ledger.assetDataMap.has(id)) { internal.errors.internalError('Asset with such ID already exists in testing context!') } const assetId = asUint64Cls(id ?? lazyContext.ledger.assetIdIter.next().value) @@ -87,7 +87,7 @@ export class AvmValueGenerator { reserve: Account(ZERO_ADDRESS), } const { assetId: _, ...assetData } = input ?? {} - lazyContext.ledger.assetDataMap.set(assetId.asBigInt(), { + lazyContext.ledger.assetDataMap.set(assetId, { ...defaultAssetData, ...assetData, }) @@ -96,7 +96,7 @@ export class AvmValueGenerator { application(input?: ApplicationContextData): Application { const id = input?.applicationId - if (id && lazyContext.ledger.applicationDataMap.has(asBigInt(id))) { + if (id && lazyContext.ledger.applicationDataMap.has(id)) { internal.errors.internalError('Application with such ID already exists in testing context!') } const applicationId = asUint64Cls(id ?? lazyContext.ledger.appIdIter.next().value) @@ -106,7 +106,7 @@ export class AvmValueGenerator { ...data.application, ...applicationData, } - lazyContext.ledger.applicationDataMap.set(applicationId.asBigInt(), data) + lazyContext.ledger.applicationDataMap.set(applicationId, data) return new ApplicationCls(applicationId.asAlgoTs()) } } diff --git a/src/value-generators/txn.ts b/src/value-generators/txn.ts index e935816..b8e3a3f 100644 --- a/src/value-generators/txn.ts +++ b/src/value-generators/txn.ts @@ -10,12 +10,11 @@ import { PaymentTransaction, TxnFields, } from '../impl/transactions' -import { asBigInt } from '../util' export class TxnValueGenerator { applicationCall(fields?: ApplicationTransactionFields): ApplicationTransaction { const params = fields ?? {} - if (params.appId && !lazyContext.ledger.applicationDataMap.has(asBigInt(params.appId.id))) { + if (params.appId && !lazyContext.ledger.applicationDataMap.has(params.appId.id)) { internal.errors.internalError(`Application ID ${params.appId.id} not found in test context`) } if (!params.appId) { From 2b8d3fbbbbc50cb675d6590758f203ecf748f5be Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 17 Oct 2024 14:05:54 +0800 Subject: [PATCH 29/85] refactor: move state implementation to testing package --- src/impl/application.ts | 7 +- src/impl/state.ts | 100 ++++++++++++++++++++++++++++ src/subcontexts/contract-context.ts | 13 ++-- src/test-execution-context.ts | 8 +++ 4 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 src/impl/state.ts diff --git a/src/impl/application.ts b/src/impl/application.ts index 4abca36..ba716b3 100644 --- a/src/impl/application.ts +++ b/src/impl/application.ts @@ -1,4 +1,4 @@ -import { Account, Application, Bytes, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, Application, Bytes, bytes, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' import { BytesMap } from '../collections/custom-key-map' import { ALWAYS_APPROVE_TEAL_PROGRAM } from '../constants' @@ -6,12 +6,13 @@ import { lazyContext } from '../context-helpers/internal-context' import { Mutable } from '../typescript-helpers' import { asBigInt, asUint64 } from '../util' import { Uint64BackedCls } from './base' +import { GlobalStateCls, LocalStateMapCls } from './state' export class ApplicationData { application: Mutable> & { appLogs: bytes[] - globalStates: BytesMap> - localStates: BytesMap> + globalStates: BytesMap> + localStates: BytesMap> } isCreating: boolean = false diff --git a/src/impl/state.ts b/src/impl/state.ts new file mode 100644 index 0000000..134570b --- /dev/null +++ b/src/impl/state.ts @@ -0,0 +1,100 @@ +import { + Account, + bytes, + GlobalState, + GlobalStateOptions, + internal, + LocalState, + LocalStateForAccount, + Uint64, +} from '@algorandfoundation/algorand-typescript' +import { asBytes, asBytesCls } from '../util' + +export class GlobalStateCls { + private readonly _type: string = GlobalStateCls.name + + #value: ValueType | undefined + key: bytes | undefined + + delete: () => void = () => { + if (this.#value instanceof internal.primitives.Uint64Cls) { + this.#value = Uint64(0) as ValueType + } else { + this.#value = undefined + } + } + + static [Symbol.hasInstance](x: unknown): x is GlobalStateCls { + return x instanceof Object && '_type' in x && (x as { _type: string })['_type'] === GlobalStateCls.name + } + + get value(): ValueType { + if (this.#value === undefined) { + throw new internal.errors.AssertError('value is not set') + } + return this.#value + } + + set value(v: ValueType) { + this.#value = v + } + + get hasValue(): boolean { + return this.#value !== undefined + } + + constructor(key?: bytes | string, value?: ValueType) { + this.key = key !== undefined ? asBytes(key) : undefined + this.#value = value + } +} + +export class LocalStateCls { + #value: ValueType | undefined + delete: () => void = () => { + if (this.#value instanceof internal.primitives.Uint64Cls) { + this.#value = Uint64(0) as ValueType + } else { + this.#value = undefined + } + } + get value(): ValueType { + if (this.#value === undefined) { + throw new internal.errors.AssertError('value is not set') + } + return this.#value + } + + set value(v: ValueType) { + this.#value = v + } + + get hasValue(): boolean { + return this.#value !== undefined + } +} + +export class LocalStateMapCls { + #value = new Map>() + + getValue(account: Account): LocalStateCls { + const accountString = asBytesCls(account.bytes).valueOf() + if (!this.#value.has(accountString)) { + this.#value.set(accountString, new LocalStateCls()) + } + return this.#value.get(accountString)! + } +} + +export function createGlobalState(options?: GlobalStateOptions): GlobalState { + return new GlobalStateCls(options?.key, options?.initialValue) +} + +export function createLocalState(options?: { key?: bytes | string }): LocalState { + function localStateInternal(account: Account): LocalStateForAccount { + return localStateInternal.map.getValue(account) + } + localStateInternal.key = options?.key + localStateInternal.map = new LocalStateMapCls() + return localStateInternal +} diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 8e91ce1..e24c1f2 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -1,10 +1,11 @@ -import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, internal } from '@algorandfoundation/algorand-typescript' +import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract } from '@algorandfoundation/algorand-typescript' import { getAbiMetadata } from '../abi-metadata' import { BytesMap } from '../collections/custom-key-map' import { lazyContext } from '../context-helpers/internal-context' import { AccountCls } from '../impl/account' import { ApplicationCls } from '../impl/application' import { AssetCls } from '../impl/asset' +import { GlobalStateCls, LocalStateMapCls } from '../impl/state' import { ApplicationTransaction, AssetConfigTransaction, @@ -25,8 +26,8 @@ interface IConstructor { type StateTotals = Pick interface States { - globalStates: BytesMap> - localStates: BytesMap> + globalStates: BytesMap> + localStates: BytesMap> totals: StateTotals } @@ -39,13 +40,13 @@ const isUint64GenericType = (typeName: string | undefined) => { const extractStates = (contract: BaseContract): States => { const stateTotals = { globalNumBytes: 0, globalNumUint: 0, localNumBytes: 0, localNumUint: 0 } const states = { - globalStates: new BytesMap>(), - localStates: new BytesMap>(), + globalStates: new BytesMap>(), + localStates: new BytesMap>(), totals: stateTotals, } Object.entries(contract).forEach(([key, value]) => { const isLocalState = value instanceof Function && value.name === 'localStateInternal' - const isGlobalState = value instanceof internal.state.GlobalStateCls + const isGlobalState = value instanceof GlobalStateCls if (isLocalState || isGlobalState) { // set key using property name if not already set if (value.key === undefined) value.key = Bytes(key) diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 73415d0..675bb0b 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -15,6 +15,7 @@ import { payment as itxnPayment, submitGroup as itxnSubmitGroup, } from './impl/inner-transactions' +import { createGlobalState, createLocalState } from './impl/state' import { ContractContext } from './subcontexts/contract-context' import { LedgerContext } from './subcontexts/ledger-context' import { TransactionContext } from './subcontexts/transaction-context' @@ -109,6 +110,13 @@ export class TestExecutionContext implements internal.ExecutionContext { } } + get state() { + return { + createGlobalState, + createLocalState, + } + } + reset() { this.#contractContext = new ContractContext() this.#ledgerContext = new LedgerContext() From b63d78aa153e00e7fb1b58427eefb89d05476c06 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 17 Oct 2024 14:20:36 +0800 Subject: [PATCH 30/85] refactor: use shorthand function syntax in object literals --- src/impl/acct-params.ts | 24 ++++++++++++------------ src/impl/app-global.ts | 21 ++++++--------------- src/impl/app-params.ts | 18 +++++++++--------- src/impl/asset-holding.ts | 4 ++-- src/impl/asset-params.ts | 24 ++++++++++++------------ 5 files changed, 41 insertions(+), 50 deletions(-) diff --git a/src/impl/acct-params.ts b/src/impl/acct-params.ts index 4632f01..2893135 100644 --- a/src/impl/acct-params.ts +++ b/src/impl/acct-params.ts @@ -22,51 +22,51 @@ export const minBalance = (a: Account | internal.primitives.StubUint64Compat): u } export const AcctParams: internal.opTypes.AcctParamsType = { - acctBalance: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctBalance(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.balance, acct.balance !== 0] }, - acctMinBalance: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctMinBalance(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.minBalance, acct.balance !== 0] }, - acctAuthAddr: function (a: Account | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + acctAuthAddr(a: Account | internal.primitives.StubUint64Compat): readonly [Account, boolean] { const acct = getAccount(a) return [acct.authAddress, acct.balance !== 0] }, - acctTotalNumUint: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalNumUint(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalNumUint, acct.balance !== 0] }, - acctTotalNumByteSlice: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalNumByteSlice(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalNumByteSlice, acct.balance !== 0] }, - acctTotalExtraAppPages: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalExtraAppPages(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalExtraAppPages, acct.balance !== 0] }, - acctTotalAppsCreated: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalAppsCreated(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalAppsCreated, acct.balance !== 0] }, - acctTotalAppsOptedIn: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalAppsOptedIn(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalAppsOptedIn, acct.balance !== 0] }, - acctTotalAssetsCreated: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalAssetsCreated(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalAssetsCreated, acct.balance !== 0] }, - acctTotalAssets: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalAssets(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalAssets, acct.balance !== 0] }, - acctTotalBoxes: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalBoxes(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalBoxes, acct.balance !== 0] }, - acctTotalBoxBytes: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + acctTotalBoxBytes(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) return [acct.totalBoxBytes, acct.balance !== 0] }, diff --git a/src/impl/app-global.ts b/src/impl/app-global.ts index b97665c..1c31acc 100644 --- a/src/impl/app-global.ts +++ b/src/impl/app-global.ts @@ -4,19 +4,16 @@ import { asBytes } from '../util' import { getApp } from './app-params' export const AppGlobal: internal.opTypes.AppGlobalType = { - delete: function (a: internal.primitives.StubBytesCompat): void { + delete(a: internal.primitives.StubBytesCompat): void { lazyContext.ledger.setGlobalState(lazyContext.activeApplication, a, undefined) }, - getBytes: function (a: internal.primitives.StubBytesCompat): bytes { + getBytes(a: internal.primitives.StubBytesCompat): bytes { return this.getExBytes(0, asBytes(a))[0] }, - getUint64: function (a: internal.primitives.StubBytesCompat): uint64 { + getUint64(a: internal.primitives.StubBytesCompat): uint64 { return this.getExUint64(0, asBytes(a))[0] }, - getExBytes: function ( - a: Application | internal.primitives.StubUint64Compat, - b: internal.primitives.StubBytesCompat, - ): readonly [bytes, boolean] { + getExBytes(a: Application | internal.primitives.StubUint64Compat, b: internal.primitives.StubBytesCompat): readonly [bytes, boolean] { const app = getApp(a) if (app === undefined) { return [Bytes(), false] @@ -27,10 +24,7 @@ export const AppGlobal: internal.opTypes.AppGlobalType = { } return [state!.value as bytes, exists] }, - getExUint64: function ( - a: Application | internal.primitives.StubUint64Compat, - b: internal.primitives.StubBytesCompat, - ): readonly [uint64, boolean] { + getExUint64(a: Application | internal.primitives.StubUint64Compat, b: internal.primitives.StubBytesCompat): readonly [uint64, boolean] { const app = getApp(a) if (app === undefined) { return [Uint64(0), false] @@ -41,10 +35,7 @@ export const AppGlobal: internal.opTypes.AppGlobalType = { } return [state!.value as uint64, exists] }, - put: function ( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat, - ): void { + put(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat | internal.primitives.StubBytesCompat): void { lazyContext.ledger.setGlobalState(lazyContext.activeApplication, a, b) }, } diff --git a/src/impl/app-params.ts b/src/impl/app-params.ts index 6d4d0db..e1b339c 100644 --- a/src/impl/app-params.ts +++ b/src/impl/app-params.ts @@ -24,39 +24,39 @@ export const getApp = (app: Application | internal.primitives.StubUint64Compat): } export const AppParams: internal.opTypes.AppParamsType = { - appApprovalProgram: function (a: Application | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + appApprovalProgram(a: Application | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { const app = getApp(a) return app === undefined ? [Bytes(), false] : [app.approvalProgram, true] }, - appClearStateProgram: function (a: Application | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + appClearStateProgram(a: Application | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { const app = getApp(a) return app === undefined ? [Bytes(), false] : [app.clearStateProgram, true] }, - appGlobalNumUint: function (a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + appGlobalNumUint(a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const app = getApp(a) return app === undefined ? [Uint64(0), false] : [app.globalNumUint, true] }, - appGlobalNumByteSlice: function (a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + appGlobalNumByteSlice(a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const app = getApp(a) return app === undefined ? [Uint64(0), false] : [app.globalNumBytes, true] }, - appLocalNumUint: function (a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + appLocalNumUint(a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const app = getApp(a) return app === undefined ? [Uint64(0), false] : [app.localNumUint, true] }, - appLocalNumByteSlice: function (a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + appLocalNumByteSlice(a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const app = getApp(a) return app === undefined ? [Uint64(0), false] : [app.localNumBytes, true] }, - appExtraProgramPages: function (a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + appExtraProgramPages(a: Application | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const app = getApp(a) return app === undefined ? [Uint64(0), false] : [app.extraProgramPages, true] }, - appCreator: function (a: Application | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + appCreator(a: Application | internal.primitives.StubUint64Compat): readonly [Account, boolean] { const app = getApp(a) return app === undefined ? [Account(), false] : [app.creator, true] }, - appAddress: function (a: Application | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + appAddress(a: Application | internal.primitives.StubUint64Compat): readonly [Account, boolean] { const app = getApp(a) return app === undefined ? [Account(), false] : [app.address, true] }, diff --git a/src/impl/asset-holding.ts b/src/impl/asset-holding.ts index c5bb593..1da7f3e 100644 --- a/src/impl/asset-holding.ts +++ b/src/impl/asset-holding.ts @@ -23,14 +23,14 @@ const getAssetHolding = ( } export const AssetHolding: internal.opTypes.AssetHoldingType = { - assetBalance: function ( + assetBalance( a: Account | internal.primitives.StubUint64Compat, b: Asset | internal.primitives.StubUint64Compat, ): readonly [uint64, boolean] { const holding = getAssetHolding(a, b) return holding === undefined ? [Uint64(0), false] : [holding.balance, true] }, - assetFrozen: function ( + assetFrozen( a: Account | internal.primitives.StubUint64Compat, b: Asset | internal.primitives.StubUint64Compat, ): readonly [boolean, boolean] { diff --git a/src/impl/asset-params.ts b/src/impl/asset-params.ts index be4d48b..05a4129 100644 --- a/src/impl/asset-params.ts +++ b/src/impl/asset-params.ts @@ -24,51 +24,51 @@ export const getAsset = (asset: Asset | internal.primitives.StubUint64Compat): A } export const AssetParams: internal.opTypes.AssetParamsType = { - assetTotal: function (a: Asset | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + assetTotal(a: Asset | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const asset = getAsset(a) return asset === undefined ? [Uint64(0), false] : [asset.total, true] }, - assetDecimals: function (a: Asset | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + assetDecimals(a: Asset | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const asset = getAsset(a) return asset === undefined ? [Uint64(0), false] : [asset.decimals, true] }, - assetDefaultFrozen: function (a: Asset | internal.primitives.StubUint64Compat): readonly [boolean, boolean] { + assetDefaultFrozen(a: Asset | internal.primitives.StubUint64Compat): readonly [boolean, boolean] { const asset = getAsset(a) return asset === undefined ? [false, false] : [asset.defaultFrozen, true] }, - assetUnitName: function (a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + assetUnitName(a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { const asset = getAsset(a) return asset === undefined ? [Bytes(), false] : [asset.unitName, true] }, - assetName: function (a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + assetName(a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { const asset = getAsset(a) return asset === undefined ? [Bytes(), false] : [asset.name, true] }, - assetUrl: function (a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + assetUrl(a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { const asset = getAsset(a) return asset === undefined ? [Bytes(), false] : [asset.url, true] }, - assetMetadataHash: function (a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { + assetMetadataHash(a: Asset | internal.primitives.StubUint64Compat): readonly [bytes, boolean] { const asset = getAsset(a) return asset === undefined ? [Bytes(), false] : [asset.metadataHash, true] }, - assetManager: function (a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + assetManager(a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { const asset = getAsset(a) return asset === undefined ? [Account(), false] : [asset.manager, true] }, - assetReserve: function (a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + assetReserve(a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { const asset = getAsset(a) return asset === undefined ? [Account(), false] : [asset.reserve, true] }, - assetFreeze: function (a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + assetFreeze(a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { const asset = getAsset(a) return asset === undefined ? [Account(), false] : [asset.freeze, true] }, - assetClawback: function (a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + assetClawback(a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { const asset = getAsset(a) return asset === undefined ? [Account(), false] : [asset.clawback, true] }, - assetCreator: function (a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { + assetCreator(a: Asset | internal.primitives.StubUint64Compat): readonly [Account, boolean] { const asset = getAsset(a) return asset === undefined ? [Account(), false] : [asset.creator, true] }, From e7d4a3250bceb34566b51e5781eb437bdcf83e69 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 29 Oct 2024 10:37:17 +0800 Subject: [PATCH 31/85] chore: update algots package version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index e700db0..9c805f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.9", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.12", "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", "algosdk": "^2.9.0", "elliptic": "^6.5.7", @@ -105,9 +105,9 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.9", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.9.tgz", - "integrity": "sha512-F5Sungkl0z6y1nu0VGN9ZSkAxHemTM/JIycdcXH60rWinZrQLUXTGVkPvrrQ0h+OyZrgBSdTOsJ7xh9l10Ylzw==", + "version": "0.0.1-alpha.12", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.12.tgz", + "integrity": "sha512-No31NwjkC/KgV+jnsX/Ko/TG/k3BfnRHLmzxgKleQVewrgmQwextfRYixf+Gv6H9X0fzygMq9JjwLAO6V3pjSA==", "peerDependencies": { "tslib": "^2.6.2" } diff --git a/package.json b/package.json index 8dbbd3f..f36e273 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ }, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.9", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.12", "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", "algosdk": "^2.9.0", "elliptic": "^6.5.7", From b3b8405be27e1fb83b7169424c3da83607530660 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 29 Oct 2024 10:48:12 +0800 Subject: [PATCH 32/85] chore: fix npm audit vlunerability --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9c805f6..cc92893 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4134,9 +4134,9 @@ "license": "MIT" }, "node_modules/elliptic": { - "version": "6.5.7", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", - "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.0.tgz", + "integrity": "sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", From b280f92292d8c09c5bf22107a042ce9d4673a337 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 17 Oct 2024 17:57:14 +0800 Subject: [PATCH 33/85] feat: implement AppLocal and add tests for it --- src/impl/app-local.ts | 58 +++ src/impl/application.ts | 6 +- src/impl/index.ts | 1 + src/impl/state.ts | 12 +- src/subcontexts/contract-context.ts | 8 +- src/subcontexts/ledger-context.ts | 31 +- tests/artifacts/state-ops/contract.algo.ts | 73 +++ .../data/StateAppLocalContract.approval.teal | 419 ++++++++++++++++++ .../data/StateAppLocalContract.arc32.json | 251 +++++++++++ .../data/StateAppLocalContract.clear.teal | 7 + .../StateAppLocalExContract.approval.teal | 77 ++++ .../data/StateAppLocalExContract.arc32.json | 63 +++ .../data/StateAppLocalExContract.clear.teal | 7 + tests/state-op-codes.spec.ts | 82 ++++ 14 files changed, 1081 insertions(+), 14 deletions(-) create mode 100644 src/impl/app-local.ts create mode 100644 tests/artifacts/state-ops/data/StateAppLocalContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/StateAppLocalContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/StateAppLocalContract.clear.teal create mode 100644 tests/artifacts/state-ops/data/StateAppLocalExContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/StateAppLocalExContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/StateAppLocalExContract.clear.teal diff --git a/src/impl/app-local.ts b/src/impl/app-local.ts new file mode 100644 index 0000000..f478fce --- /dev/null +++ b/src/impl/app-local.ts @@ -0,0 +1,58 @@ +import { Account, Application, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' +import { asBytes } from '../util' +import { getAccount } from './acct-params' +import { getApp } from './app-params' + +export const AppLocal: internal.opTypes.AppLocalType = { + delete: function (a: Account | internal.primitives.StubUint64Compat, b: internal.primitives.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 { + const account = getAccount(a) + return this.getExBytes(account, 0, asBytes(b))[0] + }, + getUint64: function (a: Account | internal.primitives.StubUint64Compat, b: internal.primitives.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] { + const app = getApp(b) + const account = getAccount(a) + if (app === undefined || account === undefined) { + return [Bytes(), false] + } + const [state, exists] = lazyContext.ledger.getLocalState(app, account, c) + if (!exists) { + return [Bytes(), false] + } + return [state!.value as bytes, exists] + }, + getExUint64: function ( + a: Account | internal.primitives.StubUint64Compat, + b: Application | internal.primitives.StubUint64Compat, + c: internal.primitives.StubBytesCompat, + ): readonly [uint64, boolean] { + const app = getApp(b) + const account = getAccount(a) + if (app === undefined || account === undefined) { + return [Uint64(0), false] + } + const [state, exists] = lazyContext.ledger.getLocalState(app, account, c) + if (!exists) { + return [Uint64(0), false] + } + return [state!.value as uint64, exists] + }, + put: function (a: Account | internal.primitives.StubUint64Compat, b: internal.primitives.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/application.ts b/src/impl/application.ts index ba716b3..c9b53c3 100644 --- a/src/impl/application.ts +++ b/src/impl/application.ts @@ -1,4 +1,4 @@ -import { Account, Application, Bytes, bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, Application, Bytes, bytes, LocalState, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' import { BytesMap } from '../collections/custom-key-map' import { ALWAYS_APPROVE_TEAL_PROGRAM } from '../constants' @@ -6,13 +6,13 @@ import { lazyContext } from '../context-helpers/internal-context' import { Mutable } from '../typescript-helpers' import { asBigInt, asUint64 } from '../util' import { Uint64BackedCls } from './base' -import { GlobalStateCls, LocalStateMapCls } from './state' +import { GlobalStateCls } from './state' export class ApplicationData { application: Mutable> & { appLogs: bytes[] globalStates: BytesMap> - localStates: BytesMap> + localStates: BytesMap> } isCreating: boolean = false diff --git a/src/impl/index.ts b/src/impl/index.ts index d786050..90f6469 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -1,5 +1,6 @@ export { AcctParams, balance, minBalance } from './acct-params' export { AppGlobal } from './app-global' +export { AppLocal } from './app-local' export { AppParams } from './app-params' export { AssetHolding } from './asset-holding' export { AssetParams } from './asset-params' diff --git a/src/impl/state.ts b/src/impl/state.ts index 134570b..e59b9f8 100644 --- a/src/impl/state.ts +++ b/src/impl/state.ts @@ -8,7 +8,8 @@ import { LocalStateForAccount, Uint64, } from '@algorandfoundation/algorand-typescript' -import { asBytes, asBytesCls } from '../util' +import { AccountMap } from '../collections/custom-key-map' +import { asBytes } from '../util' export class GlobalStateCls { private readonly _type: string = GlobalStateCls.name @@ -75,14 +76,13 @@ export class LocalStateCls { } export class LocalStateMapCls { - #value = new Map>() + #value = new AccountMap>() getValue(account: Account): LocalStateCls { - const accountString = asBytesCls(account.bytes).valueOf() - if (!this.#value.has(accountString)) { - this.#value.set(accountString, new LocalStateCls()) + if (!this.#value.has(account)) { + this.#value.set(account, new LocalStateCls()) } - return this.#value.get(accountString)! + return this.#value.getOrFail(account)! } } diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index e24c1f2..e9bfacc 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -1,11 +1,11 @@ -import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract } from '@algorandfoundation/algorand-typescript' +import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, LocalState } from '@algorandfoundation/algorand-typescript' import { getAbiMetadata } from '../abi-metadata' import { BytesMap } from '../collections/custom-key-map' import { lazyContext } from '../context-helpers/internal-context' import { AccountCls } from '../impl/account' import { ApplicationCls } from '../impl/application' import { AssetCls } from '../impl/asset' -import { GlobalStateCls, LocalStateMapCls } from '../impl/state' +import { GlobalStateCls } from '../impl/state' import { ApplicationTransaction, AssetConfigTransaction, @@ -27,7 +27,7 @@ type StateTotals = Pick> - localStates: BytesMap> + localStates: BytesMap> totals: StateTotals } @@ -41,7 +41,7 @@ const extractStates = (contract: BaseContract): States => { const stateTotals = { globalNumBytes: 0, globalNumUint: 0, localNumBytes: 0, localNumUint: 0 } const states = { globalStates: new BytesMap>(), - localStates: new BytesMap>(), + localStates: new BytesMap>(), totals: stateTotals, } Object.entries(contract).forEach(([key, value]) => { diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index d6d158e..c9cb61a 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -1,4 +1,4 @@ -import { Account, Application, Asset, BaseContract, internal } from '@algorandfoundation/algorand-typescript' +import { Account, Application, Asset, BaseContract, internal, LocalStateForAccount } from '@algorandfoundation/algorand-typescript' import { AccountMap, Uint64Map } from '../collections/custom-key-map' import { MAX_UINT64 } from '../constants' import { AccountData, AssetHolding } from '../impl/account' @@ -123,4 +123,33 @@ export class LedgerContext { globalState.value = asMaybeUint64Cls(value) ?? asMaybeBytesCls(value) } } + + getLocalState( + app: Application, + account: Account, + key: internal.primitives.StubBytesCompat, + ): [LocalStateForAccount, true] | [undefined, false] { + const appData = this.applicationDataMap.get(app.id) + if (!appData?.application.localStates.has(key)) { + return [undefined, false] + } + const localState = appData.application.localStates.getOrFail(key) + return [localState(account), 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) + if (value === undefined) { + accountLocalState.delete() + } else { + accountLocalState.value = asMaybeUint64Cls(value) ?? asMaybeBytesCls(value) + } + } } diff --git a/tests/artifacts/state-ops/contract.algo.ts b/tests/artifacts/state-ops/contract.algo.ts index 0b29457..82cf5e8 100644 --- a/tests/artifacts/state-ops/contract.algo.ts +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -10,6 +10,7 @@ import { Global, GlobalState, itxn, + LocalState, op, TransactionType, Txn, @@ -405,6 +406,78 @@ export class StateAppGlobalContract extends arc4.Contract { } } +export class StateAppLocalExContract extends arc4.Contract { + localUint64 = LocalState({ key: 'local_uint64' }) + localBytes = LocalState({ key: 'local_bytes' }) + + // TODO: uncomment when arc4 types are ready + // localArc4Bytes = LocalState({ key: "local_arc4_bytes" }) + + @arc4.abimethod({ allowActions: ['OptIn'] }) + optIn(): void { + this.localBytes(Global.creatorAddress).value = Bytes('dummy_bytes_from_external_contract') + this.localUint64(Global.creatorAddress).value = Uint64(99) + // TODO: uncomment when arc4 types are ready + // this.localArc4Bytes(Global.creatorAddress).value = arc4.DynamicBytes("dummy_arc4_bytes") + } +} + +export class StateAppLocalContract extends arc4.Contract { + localUint64 = LocalState({ key: 'local_uint64' }) + localBytes = LocalState({ key: 'local_bytes' }) + + @arc4.abimethod({ allowActions: ['OptIn'] }) + opt_in() { + this.localBytes(Global.creatorAddress).value = Bytes('dummy_bytes') + this.localUint64(Global.creatorAddress).value = Uint64(999) + } + + @arc4.abimethod() + verify_get_bytes(a: Account, b: bytes): bytes { + const value = op.AppLocal.getBytes(a, b) + return value + } + + @arc4.abimethod() + verify_get_uint64(a: Account, b: bytes): uint64 { + const value = op.AppLocal.getUint64(a, b) + return value + } + + @arc4.abimethod() + verify_get_ex_bytes(a: Account, b: Application, c: bytes): bytes { + const [value, _val] = op.AppLocal.getExBytes(a, b, c) + return value + } + + @arc4.abimethod() + verify_get_ex_uint64(a: Account, b: Application, c: bytes): uint64 { + const [value, _val] = op.AppLocal.getExUint64(a, b, c) + return value + } + + @arc4.abimethod() + verify_delete(a: Account, b: bytes): void { + op.AppLocal.delete(a, b) + } + + @arc4.abimethod() + verify_exists(a: Account, b: bytes): boolean { + const [_value, exists] = op.AppLocal.getExUint64(a, 0, b) + return exists + } + + @arc4.abimethod() + verify_put_uint64(a: Account, b: bytes, c: uint64): void { + op.AppLocal.put(a, b, c) + } + + @arc4.abimethod() + verify_put_bytes(a: Account, b: bytes, c: bytes): void { + op.AppLocal.put(a, b, c) + } +} + export class ITxnOpsContract extends arc4.Contract { @arc4.abimethod() public verify_itxn_ops() { diff --git a/tests/artifacts/state-ops/data/StateAppLocalContract.approval.teal b/tests/artifacts/state-ops/data/StateAppLocalContract.approval.teal new file mode 100644 index 0000000..d373649 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppLocalContract.approval.teal @@ -0,0 +1,419 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAppLocalContract.approval_program: + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@13 + method "opt_in()void" + method "verify_get_bytes(account,byte[])byte[]" + method "verify_get_uint64(account,byte[])uint64" + method "verify_get_ex_bytes(account,application,byte[])byte[]" + method "verify_get_ex_uint64(account,application,byte[])uint64" + method "verify_delete(account,byte[])void" + method "verify_exists(account,byte[])bool" + method "verify_put_uint64(account,byte[],uint64)void" + method "verify_put_bytes(account,byte[],byte[])void" + txna ApplicationArgs 0 + match main_opt_in_route@2 main_verify_get_bytes_route@3 main_verify_get_uint64_route@4 main_verify_get_ex_bytes_route@5 main_verify_get_ex_uint64_route@6 main_verify_delete_route@7 main_verify_exists_route@8 main_verify_put_uint64_route@9 main_verify_put_bytes_route@10 + err // reject transaction + +main_opt_in_route@2: + // tests/artifacts/StateOps/contract.py:361 + // @arc4.abimethod(allow_actions=["OptIn"]) + txn OnCompletion + int OptIn + == + assert // OnCompletion is OptIn + txn ApplicationID + assert // is not creating + callsub opt_in + int 1 + return + +main_verify_get_bytes_route@3: + // tests/artifacts/StateOps/contract.py:366 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/StateOps/contract.py:366 + // @arc4.abimethod() + callsub verify_get_bytes + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_get_uint64_route@4: + // tests/artifacts/StateOps/contract.py:371 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/StateOps/contract.py:371 + // @arc4.abimethod() + callsub verify_get_uint64 + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_get_ex_bytes_route@5: + // tests/artifacts/StateOps/contract.py:376 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + btoi + txnas Applications + txna ApplicationArgs 3 + extract 2 0 + // tests/artifacts/StateOps/contract.py:376 + // @arc4.abimethod() + callsub verify_get_ex_bytes + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_get_ex_uint64_route@6: + // tests/artifacts/StateOps/contract.py:381 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + btoi + txnas Applications + txna ApplicationArgs 3 + extract 2 0 + // tests/artifacts/StateOps/contract.py:381 + // @arc4.abimethod() + callsub verify_get_ex_uint64 + itob + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_delete_route@7: + // tests/artifacts/StateOps/contract.py:386 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/StateOps/contract.py:386 + // @arc4.abimethod() + callsub verify_delete + int 1 + return + +main_verify_exists_route@8: + // tests/artifacts/StateOps/contract.py:390 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/StateOps/contract.py:390 + // @arc4.abimethod() + callsub verify_exists + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + int 1 + return + +main_verify_put_uint64_route@9: + // tests/artifacts/StateOps/contract.py:395 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + btoi + // tests/artifacts/StateOps/contract.py:395 + // @arc4.abimethod() + callsub verify_put_uint64 + int 1 + return + +main_verify_put_bytes_route@10: + // tests/artifacts/StateOps/contract.py:399 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is not creating + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + txna ApplicationArgs 1 + btoi + txnas Accounts + txna ApplicationArgs 2 + extract 2 0 + txna ApplicationArgs 3 + extract 2 0 + // tests/artifacts/StateOps/contract.py:399 + // @arc4.abimethod() + callsub verify_put_bytes + int 1 + return + +main_bare_routing@13: + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.StateOps.contract.StateAppLocalContract.opt_in() -> void: +opt_in: + // tests/artifacts/StateOps/contract.py:361-362 + // @arc4.abimethod(allow_actions=["OptIn"]) + // def opt_in(self) -> None: + proto 0 0 + // tests/artifacts/StateOps/contract.py:363 + // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes") + global CreatorAddress + // tests/artifacts/StateOps/contract.py:358 + // key="local_bytes", + byte "local_bytes" + // tests/artifacts/StateOps/contract.py:363 + // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes") + byte 0x64756d6d795f6279746573 + app_local_put + // tests/artifacts/StateOps/contract.py:364 + // self.local_uint64[Global.creator_address] = UInt64(999) + global CreatorAddress + // tests/artifacts/StateOps/contract.py:353 + // key="local_uint64", + byte "local_uint64" + // tests/artifacts/StateOps/contract.py:364 + // self.local_uint64[Global.creator_address] = UInt64(999) + int 999 + app_local_put + retsub + + +// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_bytes(a: bytes, b: bytes) -> bytes: +verify_get_bytes: + // tests/artifacts/StateOps/contract.py:366-367 + // @arc4.abimethod() + // def verify_get_bytes(self, a: Account, b: Bytes) -> Bytes: + proto 2 1 + // tests/artifacts/StateOps/contract.py:368 + // value = op.AppLocal.get_bytes(a, b) + frame_dig -2 + frame_dig -1 + app_local_get + // tests/artifacts/StateOps/contract.py:369 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_uint64(a: bytes, b: bytes) -> uint64: +verify_get_uint64: + // tests/artifacts/StateOps/contract.py:371-372 + // @arc4.abimethod() + // def verify_get_uint64(self, a: Account, b: Bytes) -> UInt64: + proto 2 1 + // tests/artifacts/StateOps/contract.py:373 + // value = op.AppLocal.get_uint64(a, b) + frame_dig -2 + frame_dig -1 + app_local_get + // tests/artifacts/StateOps/contract.py:374 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_ex_bytes(a: bytes, b: uint64, c: bytes) -> bytes: +verify_get_ex_bytes: + // tests/artifacts/StateOps/contract.py:376-377 + // @arc4.abimethod() + // def verify_get_ex_bytes(self, a: Account, b: Application, c: Bytes) -> Bytes: + proto 3 1 + // tests/artifacts/StateOps/contract.py:378 + // value, _val = op.AppLocal.get_ex_bytes(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + app_local_get_ex + pop + // tests/artifacts/StateOps/contract.py:379 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_ex_uint64(a: bytes, b: uint64, c: bytes) -> uint64: +verify_get_ex_uint64: + // tests/artifacts/StateOps/contract.py:381-382 + // @arc4.abimethod() + // def verify_get_ex_uint64(self, a: Account, b: Application, c: Bytes) -> UInt64: + proto 3 1 + // tests/artifacts/StateOps/contract.py:383 + // value, _val = op.AppLocal.get_ex_uint64(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + app_local_get_ex + pop + // tests/artifacts/StateOps/contract.py:384 + // return value + retsub + + +// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_delete(a: bytes, b: bytes) -> void: +verify_delete: + // tests/artifacts/StateOps/contract.py:386-387 + // @arc4.abimethod() + // def verify_delete(self, a: Account, b: Bytes) -> None: + proto 2 0 + // tests/artifacts/StateOps/contract.py:388 + // op.AppLocal.delete(a, b) + frame_dig -2 + frame_dig -1 + app_local_del + retsub + + +// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_exists(a: bytes, b: bytes) -> uint64: +verify_exists: + // tests/artifacts/StateOps/contract.py:390-391 + // @arc4.abimethod() + // def verify_exists(self, a: Account, b: Bytes) -> bool: + proto 2 1 + // tests/artifacts/StateOps/contract.py:392 + // _value, exists = op.AppLocal.get_ex_uint64(a, 0, b) + frame_dig -2 + int 0 + frame_dig -1 + app_local_get_ex + bury 1 + // tests/artifacts/StateOps/contract.py:393 + // return exists + retsub + + +// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_put_uint64(a: bytes, b: bytes, c: uint64) -> void: +verify_put_uint64: + // tests/artifacts/StateOps/contract.py:395-396 + // @arc4.abimethod() + // def verify_put_uint64(self, a: Account, b: Bytes, c: UInt64) -> None: + proto 3 0 + // tests/artifacts/StateOps/contract.py:397 + // op.AppLocal.put(a, b, c) + frame_dig -3 + frame_dig -2 + frame_dig -1 + app_local_put + retsub + + +// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_put_bytes(a: bytes, b: bytes, c: bytes) -> void: +verify_put_bytes: + // tests/artifacts/StateOps/contract.py:399-400 + // @arc4.abimethod() + // def verify_put_bytes(self, a: Account, b: Bytes, c: Bytes) -> None: + proto 3 0 + // tests/artifacts/StateOps/contract.py:401 + // 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 new file mode 100644 index 0000000..f5ed19a --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppLocalContract.arc32.json @@ -0,0 +1,251 @@ +{ + "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": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxMwogICAgbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICBtZXRob2QgInZlcmlmeV9nZXRfYnl0ZXMoYWNjb3VudCxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZ2V0X3VpbnQ2NChhY2NvdW50LGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9nZXRfZXhfYnl0ZXMoYWNjb3VudCxhcHBsaWNhdGlvbixieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhY2NvdW50LGFwcGxpY2F0aW9uLGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9kZWxldGUoYWNjb3VudCxieXRlW10pdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X2V4aXN0cyhhY2NvdW50LGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfcHV0X3VpbnQ2NChhY2NvdW50LGJ5dGVbXSx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X3B1dF9ieXRlcyhhY2NvdW50LGJ5dGVbXSxieXRlW10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fb3B0X2luX3JvdXRlQDIgbWFpbl92ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDMgbWFpbl92ZXJpZnlfZ2V0X3VpbnQ2NF9yb3V0ZUA0IG1haW5fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1IG1haW5fdmVyaWZ5X2dldF9leF91aW50NjRfcm91dGVANiBtYWluX3ZlcmlmeV9kZWxldGVfcm91dGVANyBtYWluX3ZlcmlmeV9leGlzdHNfcm91dGVAOCBtYWluX3ZlcmlmeV9wdXRfdWludDY0X3JvdXRlQDkgbWFpbl92ZXJpZnlfcHV0X2J5dGVzX3JvdXRlQDEwCiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBPcHRJbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfYnl0ZXNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldF91aW50NjRfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDkKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0OQogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF9leF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDkKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZGVsZXRlCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9leGlzdHNfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4aXN0cwogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3B1dF91aW50NjQKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3B1dF9ieXRlc19yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9wdXRfYnl0ZXMKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0OQogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC5vcHRfaW4oKSAtPiB2b2lkOgpvcHRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYxLTM2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgLy8gZGVmIG9wdF9pbihzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYzCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlcyIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNTgKICAgIC8vIGtleT0ibG9jYWxfYnl0ZXMiLAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYzCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlcyIpCiAgICBieXRlIDB4NjQ3NTZkNmQ3OTVmNjI3OTc0NjU3MwogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2NAogICAgLy8gc2VsZi5sb2NhbF91aW50NjRbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBVSW50NjQoOTk5KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUzCiAgICAvLyBrZXk9ImxvY2FsX3VpbnQ2NCIsCiAgICBieXRlICJsb2NhbF91aW50NjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY0CiAgICAvLyBzZWxmLmxvY2FsX3VpbnQ2NFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IFVJbnQ2NCg5OTkpCiAgICBpbnQgOTk5CiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9nZXRfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2dldF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjYtMzY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfYnl0ZXMoc2VsZiwgYTogQWNjb3VudCwgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY4CiAgICAvLyB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldF9ieXRlcyhhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzcxLTM3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X3VpbnQ2NChzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzczCiAgICAvLyB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldF91aW50NjQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzc0CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2dldF9leF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9nZXRfZXhfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzc2LTM3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X2V4X2J5dGVzKHNlbGYsIGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzgKICAgIC8vIHZhbHVlLCBfdmFsID0gb3AuQXBwTG9jYWwuZ2V0X2V4X2J5dGVzKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozODEtMzgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfdWludDY0KHNlbGYsIGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgzCiAgICAvLyB2YWx1ZSwgX3ZhbCA9IG9wLkFwcExvY2FsLmdldF9leF91aW50NjQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4NAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB2b2lkOgp2ZXJpZnlfZGVsZXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4Ni0zODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2RlbGV0ZShzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4OAogICAgLy8gb3AuQXBwTG9jYWwuZGVsZXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2RlbAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZXhpc3RzKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZXhpc3RzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5MC0zOTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2V4aXN0cyhzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5MgogICAgLy8gX3ZhbHVlLCBleGlzdHMgPSBvcC5BcHBMb2NhbC5nZXRfZXhfdWludDY0KGEsIDAsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5MwogICAgLy8gcmV0dXJuIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCkgLT4gdm9pZDoKdmVyaWZ5X3B1dF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzk1LTM5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfcHV0X3VpbnQ2NChzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcywgYzogVUludDY0KSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzk3CiAgICAvLyBvcC5BcHBMb2NhbC5wdXQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiB2b2lkOgp2ZXJpZnlfcHV0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5OS00MDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3B1dF9ieXRlcyhzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcywgYzogQnl0ZXMpIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDEKICAgIC8vIG9wLkFwcExvY2FsLnB1dChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 1, + "num_uints": 1 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": { + "local_bytes": { + "type": "bytes", + "key": "local_bytes" + }, + "local_uint64": { + "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.clear.teal b/tests/artifacts/state-ops/data/StateAppLocalContract.clear.teal new file mode 100644 index 0000000..573a8b4 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppLocalContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAppLocalContract.clear_state_program: + // tests/artifacts/StateOps/contract.py:349 + // class StateAppLocalContract(ARC4Contract): + int 1 + return diff --git a/tests/artifacts/state-ops/data/StateAppLocalExContract.approval.teal b/tests/artifacts/state-ops/data/StateAppLocalExContract.approval.teal new file mode 100644 index 0000000..bd92746 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppLocalExContract.approval.teal @@ -0,0 +1,77 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAppLocalExContract.approval_program: + // tests/artifacts/StateOps/contract.py:323 + // class StateAppLocalExContract(ARC4Contract): + txn NumAppArgs + bz main_bare_routing@5 + method "opt_in()void" + txna ApplicationArgs 0 + match main_opt_in_route@2 + err // reject transaction + +main_opt_in_route@2: + // tests/artifacts/StateOps/contract.py:340 + // @arc4.abimethod(allow_actions=["OptIn"]) + txn OnCompletion + int OptIn + == + assert // OnCompletion is OptIn + txn ApplicationID + assert // is not creating + callsub opt_in + int 1 + return + +main_bare_routing@5: + // tests/artifacts/StateOps/contract.py:323 + // class StateAppLocalExContract(ARC4Contract): + txn OnCompletion + ! + assert // reject transaction + txn ApplicationID + ! + assert // is creating + int 1 + return + + +// tests.artifacts.StateOps.contract.StateAppLocalExContract.opt_in() -> void: +opt_in: + // tests/artifacts/StateOps/contract.py:340-341 + // @arc4.abimethod(allow_actions=["OptIn"]) + // def opt_in(self) -> None: + proto 0 0 + // tests/artifacts/StateOps/contract.py:342 + // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes_from_external_contract") + global CreatorAddress + // tests/artifacts/StateOps/contract.py:332 + // key="local_bytes", + byte "local_bytes" + // tests/artifacts/StateOps/contract.py:342 + // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes_from_external_contract") + byte 0x64756d6d795f62797465735f66726f6d5f65787465726e616c5f636f6e7472616374 + app_local_put + // tests/artifacts/StateOps/contract.py:343 + // self.local_uint64[Global.creator_address] = UInt64(99) + global CreatorAddress + // tests/artifacts/StateOps/contract.py:327 + // key="local_uint64", + byte "local_uint64" + // tests/artifacts/StateOps/contract.py:343 + // self.local_uint64[Global.creator_address] = UInt64(99) + int 99 + app_local_put + // tests/artifacts/StateOps/contract.py:344 + // self.local_arc4_bytes[Global.creator_address] = algopy.arc4.DynamicBytes( + global CreatorAddress + // tests/artifacts/StateOps/contract.py:337 + // key="local_arc4_bytes", + byte "local_arc4_bytes" + // tests/artifacts/StateOps/contract.py:344-346 + // self.local_arc4_bytes[Global.creator_address] = algopy.arc4.DynamicBytes( + // b"dummy_arc4_bytes" + // ) + byte 0x001064756d6d795f617263345f6279746573 + app_local_put + retsub diff --git a/tests/artifacts/state-ops/data/StateAppLocalExContract.arc32.json b/tests/artifacts/state-ops/data/StateAppLocalExContract.arc32.json new file mode 100644 index 0000000..dc09a19 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppLocalExContract.arc32.json @@ -0,0 +1,63 @@ +{ + "hints": { + "opt_in()void": { + "call_config": { + "opt_in": "CALL" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjMKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdANQogICAgbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX29wdF9pbl9yb3V0ZUAyCiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBPcHRJbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0A1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMyMwogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3Qub3B0X2luKCkgLT4gdm9pZDoKb3B0X2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0MC0zNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiT3B0SW4iXSkKICAgIC8vIGRlZiBvcHRfaW4oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0MgogICAgLy8gc2VsZi5sb2NhbF9ieXRlc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IEJ5dGVzKGIiZHVtbXlfYnl0ZXNfZnJvbV9leHRlcm5hbF9jb250cmFjdCIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMzIKICAgIC8vIGtleT0ibG9jYWxfYnl0ZXMiLAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQyCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlc19mcm9tX2V4dGVybmFsX2NvbnRyYWN0IikKICAgIGJ5dGUgMHg2NDc1NmQ2ZDc5NWY2Mjc5NzQ2NTczNWY2NjcyNmY2ZDVmNjU3ODc0NjU3MjZlNjE2YzVmNjM2ZjZlNzQ3MjYxNjM3NAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0MwogICAgLy8gc2VsZi5sb2NhbF91aW50NjRbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBVSW50NjQoOTkpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjcKICAgIC8vIGtleT0ibG9jYWxfdWludDY0IiwKICAgIGJ5dGUgImxvY2FsX3VpbnQ2NCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDMKICAgIC8vIHNlbGYubG9jYWxfdWludDY0W0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gVUludDY0KDk5KQogICAgaW50IDk5CiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ0CiAgICAvLyBzZWxmLmxvY2FsX2FyYzRfYnl0ZXNbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMzcKICAgIC8vIGtleT0ibG9jYWxfYXJjNF9ieXRlcyIsCiAgICBieXRlICJsb2NhbF9hcmM0X2J5dGVzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0NC0zNDYKICAgIC8vIHNlbGYubG9jYWxfYXJjNF9ieXRlc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFsZ29weS5hcmM0LkR5bmFtaWNCeXRlcygKICAgIC8vICAgICBiImR1bW15X2FyYzRfYnl0ZXMiCiAgICAvLyApCiAgICBieXRlIDB4MDAxMDY0NzU2ZDZkNzk1ZjYxNzI2MzM0NWY2Mjc5NzQ2NTczCiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjMKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 2, + "num_uints": 1 + } + }, + "schema": { + "global": { + "declared": {}, + "reserved": {} + }, + "local": { + "declared": { + "local_arc4_bytes": { + "type": "bytes", + "key": "local_arc4_bytes" + }, + "local_bytes": { + "type": "bytes", + "key": "local_bytes" + }, + "local_uint64": { + "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.clear.teal b/tests/artifacts/state-ops/data/StateAppLocalExContract.clear.teal new file mode 100644 index 0000000..c4080e2 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppLocalExContract.clear.teal @@ -0,0 +1,7 @@ +#pragma version 10 + +tests.artifacts.StateOps.contract.StateAppLocalExContract.clear_state_program: + // tests/artifacts/StateOps/contract.py:323 + // class StateAppLocalExContract(ARC4Contract): + int 1 + return diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 27243c4..7fa0ade 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -1,4 +1,5 @@ import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' +import { ApplicationClient } 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 { afterEach, describe, expect, it, test } from 'vitest' @@ -8,6 +9,7 @@ import { testInvariant } from '../src/errors' 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 } from '../src/util' import { AppExpectingEffects } from './artifacts/created-app-asset/contract.algo' import { @@ -16,6 +18,8 @@ import { StateAcctParamsGetContract, StateAppGlobalContract, StateAppGlobalExContract, + StateAppLocalContract, + StateAppLocalExContract, StateAppParamsContract, StateAssetHoldingContract, StateAssetParamsContract, @@ -23,6 +27,8 @@ import { 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' @@ -497,4 +503,80 @@ describe('State op codes', async () => { // TODO: implement test_app_global_ex_get_arc4 test method when arc4 stubs are implemented }) + + describe('AppLocal', async () => { + const tryOptIn = async (client: ApplicationClient) => { + try { + await client.optIn({ method: 'opt_in', methodArgs: [] }) + } catch (e) { + if (!(e as DeliberateAny).message.includes('has already opted in to app')) { + throw e + } + // ignore error if account has already opted in + } + } + const appClient = await getAlgorandAppClient(appLocalAppSpecJson as AppSpec) + const [exAppClient, exApp] = await getAlgorandAppClientWithApp(appLocalExAppSpecJson as AppSpec) + await tryOptIn(appClient) + await tryOptIn(exAppClient) + + it('should be able to put, get and delete app local state', async () => { + const localNetAccount = await getLocalNetDefaultAccount() + const account = Account(Bytes.fromBase32(localNetAccount.addr)) + const bytesKey = 'local_bytes' + const uint64Key = 'local_uint64' + const bytesValue = 'test_bytes' + const uint64Value = 42 + + // put + await getAvmResult({ appClient }, 'verify_put_bytes', localNetAccount.addr, asUint8Array(bytesKey), asUint8Array(bytesValue)) + await getAvmResult({ appClient }, 'verify_put_uint64', localNetAccount.addr, asUint8Array(uint64Key), uint64Value) + + const contract = ctx.contract.create(StateAppLocalContract) + contract.verify_put_bytes(account, Bytes(bytesKey), Bytes(bytesValue)) + contract.verify_put_uint64(account, Bytes(uint64Key), Uint64(uint64Value)) + + // get + const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_bytes', localNetAccount.addr, asUint8Array(bytesKey)) + const uint64AvmResult = await getAvmResult({ appClient }, 'verify_get_uint64', localNetAccount.addr, asUint8Array(uint64Key)) + + const bytesResult = contract.verify_get_bytes(account, Bytes(bytesKey)) + const uint64Result = contract.verify_get_uint64(account, Bytes(uint64Key)) + expect(bytesResult).toEqual(bytesAvmResult) + expect(asBigInt(uint64Result)).toEqual(uint64AvmResult) + + // delete + await getAvmResult({ appClient }, 'verify_delete', localNetAccount.addr, asUint8Array(bytesKey)) + await getAvmResult({ appClient }, 'verify_delete', localNetAccount.addr, asUint8Array(uint64Key)) + contract.verify_delete(account, Bytes(bytesKey)) + contract.verify_delete(account, Bytes(uint64Key)) + + await expect(() => getAvmResult({ appClient }, 'verify_get_bytes', localNetAccount.addr, asUint8Array(bytesKey))).rejects.toThrow() + expect(() => contract.verify_get_bytes(account, Bytes(bytesKey))).toThrow('value is not set') + + const uint64AvmResult2 = await getAvmResult({ appClient }, 'verify_get_uint64', localNetAccount.addr, asUint8Array(uint64Key)) + const uint64Result2 = contract.verify_get_uint64(account, Bytes(uint64Key)) + expect(asBigInt(uint64Result2)).toEqual(uint64AvmResult2) + }) + + it('should be able to use _ex methods to get state of another app', async () => { + const key = 'local_bytes' + const localNetAccount = await getLocalNetDefaultAccount() + const account = Account(Bytes.fromBase32(localNetAccount.addr)) + const secondContract = ctx.contract.create(StateAppLocalExContract) + const secondApp = ctx.ledger.getApplicationForContract(secondContract) + expect(secondApp.localNumUint.valueOf()).toEqual(1) + expect(secondApp.localNumBytes.valueOf()).toEqual(1) + + const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_ex_bytes', localNetAccount.addr, exApp.appId, asUint8Array(key)) + + const contract = ctx.contract.create(StateAppLocalContract) + secondContract.localBytes(account).value = Bytes('dummy_bytes_from_external_contract') + const bytesResult = contract.verify_get_ex_bytes(account, secondApp, Bytes(key)) + + expect(bytesResult).toEqual(bytesAvmResult) + }) + + // TODO: implement test_app_local_ex_get_arc4 test method when arc4 stubs are implemented + }) }) From 57fd3d1d240e09368a4d1863fcdb1b180e8cd763 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 29 Oct 2024 11:04:54 +0800 Subject: [PATCH 34/85] chore: update algots package version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index cc92893..2c41b93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.12", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.13", "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", "algosdk": "^2.9.0", "elliptic": "^6.5.7", @@ -105,9 +105,9 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.12", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.12.tgz", - "integrity": "sha512-No31NwjkC/KgV+jnsX/Ko/TG/k3BfnRHLmzxgKleQVewrgmQwextfRYixf+Gv6H9X0fzygMq9JjwLAO6V3pjSA==", + "version": "0.0.1-alpha.13", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.13.tgz", + "integrity": "sha512-rm+rPwO1j3rY5i95vvu7CMsv0JkguP9fsJIe/AB9eD6pnWaR8do6cCl/LbR6ow+5/3B8nLTt00l+rbvq5ibLwg==", "peerDependencies": { "tslib": "^2.6.2" } diff --git a/package.json b/package.json index f36e273..c9d8b3f 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ }, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.12", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.13", "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", "algosdk": "^2.9.0", "elliptic": "^6.5.7", From 1fcfdfb16b58c9e9638c685d03a1a059813ac42c Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 17 Oct 2024 17:57:14 +0800 Subject: [PATCH 35/85] feat: implement AppLocal and add tests for it --- src/subcontexts/ledger-context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index c9cb61a..a5880e5 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -6,7 +6,7 @@ import { ApplicationData } from '../impl/application' import { AssetData } from '../impl/asset' import { GlobalData } from '../impl/global' import { GlobalStateCls } from '../impl/state' -import { asBigInt, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' +import { asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' interface BlockData { seed: bigint From 0bd32ec554389f2c3a1410e256e5e32b3dd3e1ae Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 21 Oct 2024 10:10:48 +0800 Subject: [PATCH 36/85] feat: implement Box and add tests for it --- src/constants.ts | 1 + src/impl/application.ts | 2 + src/impl/box.ts | 141 +++++++++++ src/impl/index.ts | 1 + src/impl/state.ts | 322 ++++++++++++++++++++++++- src/subcontexts/contract-context.ts | 31 ++- src/subcontexts/ledger-context.ts | 22 +- src/subcontexts/transaction-context.ts | 3 +- src/test-execution-context.ts | 9 +- tests/references/box.spec.ts | 101 ++++++++ 10 files changed, 614 insertions(+), 19 deletions(-) create mode 100644 src/impl/box.ts create mode 100644 tests/references/box.spec.ts diff --git a/src/constants.ts b/src/constants.ts index 88e8bc1..dd5627d 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -7,6 +7,7 @@ export const MAX_UINT64 = 2n ** 64n - 1n export const MAX_UINT512 = 2n ** 512n - 1n export const MAX_BYTES_SIZE = 4096 export const MAX_ITEMS_IN_LOG = 32 +export const MAX_BOX_SIZE = 32768 export const BITS_IN_BYTE = 8 export const DEFAULT_ACCOUNT_MIN_BALANCE = 100_000 export const DEFAULT_MAX_TXN_LIFE = 1_000 diff --git a/src/impl/application.ts b/src/impl/application.ts index c9b53c3..9d2db5e 100644 --- a/src/impl/application.ts +++ b/src/impl/application.ts @@ -13,6 +13,7 @@ export class ApplicationData { appLogs: bytes[] globalStates: BytesMap> localStates: BytesMap> + boxes: BytesMap } isCreating: boolean = false @@ -33,6 +34,7 @@ export class ApplicationData { appLogs: [], globalStates: new BytesMap(), localStates: new BytesMap(), + boxes: new BytesMap(), } } } diff --git a/src/impl/box.ts b/src/impl/box.ts new file mode 100644 index 0000000..e1c5fab --- /dev/null +++ b/src/impl/box.ts @@ -0,0 +1,141 @@ +import { Bytes, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { MAX_BOX_SIZE } from '../constants' +import { lazyContext } from '../context-helpers/internal-context' +import { asBytes, asNumber, toBytes } from '../util' + +export const Box: internal.opTypes.BoxType = { + create: function (a: internal.primitives.StubBytesCompat, b: internal.primitives.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') + } + const app = lazyContext.activeApplication + if (lazyContext.ledger.boxExists(app, name)) { + return false + } + lazyContext.ledger.setBox(app, name, Bytes(Array(size).fill(0))) + return true + }, + delete: function (a: internal.primitives.StubBytesCompat): boolean { + const name = asBytes(a) + const app = lazyContext.activeApplication + if (!lazyContext.ledger.boxExists(app, name)) { + return false + } + lazyContext.ledger.deleteBox(app, name) + return true + }, + extract: function ( + a: internal.primitives.StubBytesCompat, + b: internal.primitives.StubUint64Compat, + c: internal.primitives.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') + } + const boxContent = lazyContext.ledger.getBox(app, name) + const result = toBytes(boxContent).slice(start, start + length) + return result + }, + get: function (a: internal.primitives.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: function (a: internal.primitives.StubBytesCompat): readonly [uint64, boolean] { + const name = asBytes(a) + const app = lazyContext.activeApplication + const boxContent = lazyContext.ledger.getBox(app, name) + const bytesContent = toBytes(boxContent) + return [bytesContent.length, lazyContext.ledger.boxExists(app, name)] + }, + put: function (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubBytesCompat): void { + const name = asBytes(a) + const app = lazyContext.activeApplication + const newContent = asBytes(b) + if (lazyContext.ledger.boxExists(app, name)) { + const boxContent = lazyContext.ledger.getBox(app, name) + const bytesContent = toBytes(boxContent) + if (bytesContent.length !== newContent.length) { + throw new internal.errors.InternalError('New content length does not match existing box length') + } + } + lazyContext.ledger.setBox(app, name, newContent) + }, + replace: function ( + a: internal.primitives.StubBytesCompat, + b: internal.primitives.StubUint64Compat, + c: internal.primitives.StubBytesCompat, + ): void { + const name = asBytes(a) + const start = asNumber(b) + const newContent = asBytes(c) + const app = lazyContext.activeApplication + if (!lazyContext.ledger.boxExists(app, name)) { + throw new internal.errors.InternalError('Box does not exist') + } + const boxContent = lazyContext.ledger.getBox(app, name) + const bytesContent = toBytes(boxContent) + if (start + newContent.length > bytesContent.length) { + throw new internal.errors.InternalError('Replacement content exceeds box size') + } + const updatedContent = bytesContent + .slice(0, start) + .concat(newContent) + .concat(bytesContent.slice(start + newContent.length)) + lazyContext.ledger.setBox(app, name, Bytes(updatedContent)) + }, + resize: function (a: internal.primitives.StubBytesCompat, b: internal.primitives.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') + } + const boxContent = lazyContext.ledger.getBox(app, name) + const bytesContent = toBytes(boxContent) + let updatedContent + if (newSize > bytesContent.length) { + updatedContent = bytesContent.concat(Bytes(Array(newSize - bytesContent.length).fill(0))) + } else { + updatedContent = bytesContent.slice(0, newSize) + } + lazyContext.ledger.setBox(app, name, Bytes(updatedContent)) + }, + splice: function ( + a: internal.primitives.StubBytesCompat, + b: internal.primitives.StubUint64Compat, + c: internal.primitives.StubUint64Compat, + d: internal.primitives.StubBytesCompat, + ): void { + const name = asBytes(a) + const start = asNumber(b) + const length = asNumber(c) + const newContent = asBytes(d) + const app = lazyContext.activeApplication + if (!lazyContext.ledger.boxExists(app, name)) { + throw new internal.errors.InternalError('Box does not exist') + } + const boxContent = lazyContext.ledger.getBox(app, name) + const bytesContent = toBytes(boxContent) + if (start > bytesContent.length) { + throw new internal.errors.InternalError('Start index exceeds box size') + } + const end = Math.min(start + length, bytesContent.length) + let updatedContent = bytesContent.slice(0, start).concat(newContent).concat(bytesContent.slice(end)) + + // Adjust the size if necessary + if (updatedContent.length > bytesContent.length) { + updatedContent = updatedContent.slice(0, bytesContent.length) + } else if (updatedContent.length < bytesContent.length) { + updatedContent = updatedContent.concat(Bytes(Array(bytesContent.length - updatedContent.length).fill(0))) + } + lazyContext.ledger.setBox(app, name, Bytes(updatedContent)) + }, +} diff --git a/src/impl/index.ts b/src/impl/index.ts index 90f6469..159e731 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -4,6 +4,7 @@ export { AppLocal } from './app-local' export { AppParams } from './app-params' export { AssetHolding } from './asset-holding' export { AssetParams } from './asset-params' +export { Box } from './box' export * from './crypto' export { Global } from './global' export { GTxn } from './gtxn' diff --git a/src/impl/state.ts b/src/impl/state.ts index e59b9f8..f5229f9 100644 --- a/src/impl/state.ts +++ b/src/impl/state.ts @@ -1,15 +1,23 @@ import { Account, + Application, + BoxMap as BoxMapType, + BoxRef as BoxRefType, + Box as BoxType, + Bytes, bytes, - GlobalState, GlobalStateOptions, + GlobalState as GlobalStateType, internal, - LocalState, LocalStateForAccount, + LocalState as LocalStateType, + uint64, Uint64, } from '@algorandfoundation/algorand-typescript' import { AccountMap } from '../collections/custom-key-map' -import { asBytes } from '../util' +import { MAX_BOX_SIZE } from '../constants' +import { lazyContext } from '../context-helpers/internal-context' +import { asBytes, asNumber, toBytes } from '../util' export class GlobalStateCls { private readonly _type: string = GlobalStateCls.name @@ -17,6 +25,10 @@ export class GlobalStateCls { #value: ValueType | undefined key: bytes | undefined + get hasKey(): boolean { + return this.key !== undefined && this.key.length > 0 + } + delete: () => void = () => { if (this.#value instanceof internal.primitives.Uint64Cls) { this.#value = Uint64(0) as ValueType @@ -86,15 +98,315 @@ export class LocalStateMapCls { } } -export function createGlobalState(options?: GlobalStateOptions): GlobalState { +export function GlobalState(options?: GlobalStateOptions): GlobalStateType { return new GlobalStateCls(options?.key, options?.initialValue) } -export function createLocalState(options?: { key?: bytes | string }): LocalState { +export function LocalState(options?: { key?: bytes | string }): LocalStateType { function localStateInternal(account: Account): LocalStateForAccount { return localStateInternal.map.getValue(account) } localStateInternal.key = options?.key + localStateInternal.hasKey = options?.key !== undefined && options.key.length > 0 localStateInternal.map = new LocalStateMapCls() return localStateInternal } + +export class BoxCls { + #key: bytes | undefined + #app: Application + + private readonly _type: string = BoxCls.name + + static [Symbol.hasInstance](x: unknown): x is BoxCls { + return x instanceof Object && '_type' in x && (x as { _type: string })['_type'] === BoxCls.name + } + + constructor(key?: internal.primitives.StubBytesCompat) { + this.#key = key ? asBytes(key) : undefined + this.#app = lazyContext.activeApplication + } + + get value(): TValue { + if (!this.exists) { + throw new internal.errors.InternalError('Box has not been created') + } + return lazyContext.ledger.getBox(this.#app, this.key) + } + set value(v: TValue) { + lazyContext.ledger.setBox(this.#app, this.key, v) + } + + get hasKey(): boolean { + return this.#key !== undefined && this.#key.length > 0 + } + + get key(): bytes { + if (this.#key === undefined || this.#key.length === 0) { + throw new internal.errors.InternalError('Box key is empty') + } + return this.#key + } + + set key(key: internal.primitives.StubBytesCompat) { + this.#key = asBytes(key) + } + + get exists(): boolean { + return lazyContext.ledger.boxExists(this.#app, this.key) + } + + get length(): uint64 { + if (!this.exists) { + throw new internal.errors.InternalError('Box has not been created') + } + return toBytes(this.value).length + } + + get(options: { default: TValue }): TValue { + const [value, exists] = this.maybe() + return exists ? value : options.default + } + + delete(): boolean { + return lazyContext.ledger.deleteBox(this.#app, this.key) + } + + maybe(): readonly [TValue, boolean] { + return [lazyContext.ledger.getBox(this.#app, this.key), lazyContext.ledger.boxExists(this.#app, this.key)] + } +} + +export class BoxMapCls { + #keyPrefix: bytes | undefined + #app: Application + + private readonly _type: string = BoxMapCls.name + + static [Symbol.hasInstance](x: unknown): x is BoxMapCls { + return x instanceof Object && '_type' in x && (x as { _type: string })['_type'] === BoxMapCls.name + } + + constructor(keyPrefix?: internal.primitives.StubBytesCompat) { + this.#keyPrefix = keyPrefix ? asBytes(keyPrefix) : undefined + this.#app = lazyContext.activeApplication + } + + get hasKeyPrefix(): boolean { + 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') + } + return this.#keyPrefix + } + + set keyPrefix(keyPrefix: internal.primitives.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), 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) + return [lazyContext.ledger.getBox(this.#app, fullKey), lazyContext.ledger.boxExists(this.#app, fullKey)] + } + + length(key: TKey): uint64 { + return toBytes(this.get(key)).length + } + + private getFullKey(key: TKey): bytes { + return this.keyPrefix.concat(toBytes(key)) + } +} + +export class BoxRefCls { + #key: bytes | undefined + #app: Application + + private readonly _type: string = BoxRefCls.name + + static [Symbol.hasInstance](x: unknown): x is BoxRefCls { + return x instanceof Object && '_type' in x && (x as { _type: string })['_type'] === BoxRefCls.name + } + + constructor(key?: internal.primitives.StubBytesCompat) { + this.#key = key ? asBytes(key) : undefined + this.#app = lazyContext.activeApplication + } + + get hasKey(): boolean { + return this.#key !== undefined && this.#key.length > 0 + } + + get key(): bytes { + if (this.#key === undefined || this.#key.length === 0) { + throw new internal.errors.InternalError('Box key is empty') + } + return this.#key + } + + set key(key: internal.primitives.StubBytesCompat) { + this.#key = asBytes(key) + } + + get value(): bytes { + return lazyContext.ledger.getBox(this.#app, this.key) + } + + get exists(): boolean { + return lazyContext.ledger.boxExists(this.#app, this.key) + } + + create(options: { size: internal.primitives.StubUint64Compat }): boolean { + const size = asNumber(options.size) + if (size > MAX_BOX_SIZE) { + throw new internal.errors.InternalError(`Box size cannot exceed ${MAX_BOX_SIZE}`) + } + const [content, exists] = this.maybe() + if (exists && content.length !== size) { + throw new internal.errors.InternalError('Box already exists with a different size') + } + if (exists) { + return false + } + lazyContext.ledger.setBox(this.#app, this.key, Bytes(Array(size).fill(0))) + return true + } + + get(options: { default: internal.primitives.StubBytesCompat }): bytes { + const [value, exists] = this.maybe() + return exists ? value : asBytes(options.default) + } + + put(value: internal.primitives.StubBytesCompat): void { + const bytesValue = asBytes(value) + const [content, exists] = this.maybe() + if (exists && content.length !== bytesValue.length) { + throw new internal.errors.InternalError('Box already exists with a different size') + } + lazyContext.ledger.setBox(this.#app, this.key, bytesValue) + } + + splice( + start: internal.primitives.StubUint64Compat, + length: internal.primitives.StubUint64Compat, + value: internal.primitives.StubBytesCompat, + ): void { + const [content, exists] = this.maybe() + const startNumber = asNumber(start) + const lengthNumber = asNumber(length) + const valueBytes = asBytes(value) + if (!exists) { + throw new internal.errors.InternalError('Box has not been created') + } + if (startNumber > content.length) { + throw new internal.errors.InternalError('Start index exceeds box size') + } + const end = Math.min(startNumber + lengthNumber, content.length) + let updatedContent = content.slice(0, startNumber).concat(valueBytes).concat(content.slice(end)) + + if (updatedContent.length > content.length) { + updatedContent = updatedContent.slice(0, content.length) + } else if (updatedContent.length < content.length) { + updatedContent = updatedContent.concat(Bytes(Array(content.length - updatedContent.length).fill(0))) + } + lazyContext.ledger.setBox(this.#app, this.key, updatedContent) + } + + replace(start: internal.primitives.StubUint64Compat, value: internal.primitives.StubBytesCompat): void { + const [content, exists] = this.maybe() + const startNumber = asNumber(start) + const valueBytes = asBytes(value) + if (!exists) { + throw new internal.errors.InternalError('Box has not been created') + } + if (startNumber + valueBytes.length > content.length) { + throw new internal.errors.InternalError('Replacement content exceeds box size') + } + const updatedContent = content + .slice(0, startNumber) + .concat(valueBytes) + .concat(content.slice(startNumber + valueBytes.length)) + lazyContext.ledger.setBox(this.#app, this.key, updatedContent) + } + + extract(start: internal.primitives.StubUint64Compat, length: internal.primitives.StubUint64Compat): bytes { + const [content, exists] = this.maybe() + const startNumber = asNumber(start) + const lengthNumber = asNumber(length) + if (!exists) { + throw new internal.errors.InternalError('Box has not been created') + } + if (startNumber + lengthNumber > content.length) { + throw new internal.errors.InternalError('Index out of bounds') + } + return content.slice(startNumber, startNumber + lengthNumber) + } + delete(): boolean { + return lazyContext.ledger.deleteBox(this.#app, this.key) + } + + 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}`) + } + const [content, exists] = this.maybe() + if (!exists) { + throw new internal.errors.InternalError('Box has not been created') + } + let updatedContent + if (newSizeNumber > content.length) { + updatedContent = content.concat(Bytes(Array(newSizeNumber - content.length).fill(0))) + } else { + updatedContent = content.slice(0, newSize) + } + lazyContext.ledger.setBox(this.#app, this.key, updatedContent) + } + + maybe(): readonly [bytes, boolean] { + return [lazyContext.ledger.getBox(this.#app, this.key), lazyContext.ledger.boxExists(this.#app, this.key)] + } + + get length(): uint64 { + const [value, exists] = this.maybe() + if (!exists) { + throw new internal.errors.InternalError('Box has not been created') + } + return value.length + } +} + +export function Box(options?: { key: bytes | string }): BoxType { + return new BoxCls(options?.key) +} + +export function BoxMap(options?: { keyPrefix: bytes | string }): BoxMapType { + return new BoxMapCls(options?.keyPrefix) +} + +export function BoxRef(options?: { key: bytes | string }): BoxRefType { + return new BoxRefCls(options?.key) +} diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index e9bfacc..ae7e589 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -5,7 +5,7 @@ import { lazyContext } from '../context-helpers/internal-context' import { AccountCls } from '../impl/account' import { ApplicationCls } from '../impl/application' import { AssetCls } from '../impl/asset' -import { GlobalStateCls } from '../impl/state' +import { BoxCls, BoxMapCls, BoxRefCls, GlobalStateCls } from '../impl/state' import { ApplicationTransaction, AssetConfigTransaction, @@ -47,10 +47,17 @@ const extractStates = (contract: BaseContract): States => { Object.entries(contract).forEach(([key, value]) => { const isLocalState = value instanceof Function && value.name === 'localStateInternal' const isGlobalState = value instanceof GlobalStateCls - if (isLocalState || isGlobalState) { + const isBox = value instanceof BoxCls + const isBoxRef = value instanceof BoxRefCls + const isBoxMap = value instanceof BoxMapCls + if (isLocalState || isGlobalState || isBox || isBoxRef) { // set key using property name if not already set - if (value.key === undefined) value.key = Bytes(key) + if (!value.hasKey) value.key = Bytes(key) + } else if (isBoxMap) { + if (!value.hasKeyPrefix) value.keyPrefix = Bytes(key) + } + if (isLocalState || isGlobalState) { // capture state into the context if (isLocalState) states.localStates.set(value.key, value) else states.globalStates.set(value.key, value) @@ -123,19 +130,27 @@ export class ContractContext { } private getContractProxyHandler(isArc4: boolean): ProxyHandler> { - const onConstructed = (instance: T) => { + const onConstructed = (application: Application, instance: T) => { const states = extractStates(instance) - const application = lazyContext.any.application({ + const applicationData = lazyContext.ledger.applicationDataMap.getOrFail(application.id) + applicationData.application = { + ...applicationData.application, globalStates: states.globalStates, localStates: states.localStates, ...states.totals, - }) + } lazyContext.ledger.addAppIdContractMap(application.id, instance) } return { construct(target, args) { - const instance = new Proxy(new target(...args), { + let t: T | undefined = undefined + const application = lazyContext.any.application() + const txn = lazyContext.any.txn.applicationCall({ appId: application }) + lazyContext.txn.ensureScope([txn]).execute(() => { + t = new target(...args) + }) + const instance = new Proxy(t!, { get(target, prop, receiver) { const orig = Reflect.get(target, prop, receiver) const abiMetadata = getAbiMetadata(target, prop as string) @@ -165,7 +180,7 @@ export class ContractContext { }, }) - onConstructed(instance) + onConstructed(application, instance) return instance }, diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index a5880e5..69ebdb5 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -6,7 +6,7 @@ import { ApplicationData } from '../impl/application' import { AssetData } from '../impl/asset' import { GlobalData } from '../impl/global' import { GlobalStateCls } from '../impl/state' -import { asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' +import { asBigInt, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' interface BlockData { seed: bigint @@ -152,4 +152,24 @@ export class LedgerContext { accountLocalState.value = asMaybeUint64Cls(value) ?? asMaybeBytesCls(value) } } + + getBox(app: Application, key: internal.primitives.StubBytesCompat): TValue { + const appData = this.applicationDataMap.getOrFail(app.id) + return appData.application.boxes.get(key) as TValue + } + + setBox(app: Application, key: internal.primitives.StubBytesCompat, value: TValue): void { + const appData = this.applicationDataMap.getOrFail(app.id) + appData.application.boxes.set(key, value) + } + + deleteBox(app: Application, key: internal.primitives.StubBytesCompat): boolean { + const appData = this.applicationDataMap.getOrFail(app.id) + return appData.application.boxes.delete(key) + } + + boxExists(app: Application, key: internal.primitives.StubBytesCompat): boolean { + const appData = this.applicationDataMap.getOrFail(app.id) + return appData.application.boxes.has(key) + } } diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 1708814..5137993 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -109,8 +109,7 @@ export class TransactionContext { } exportLogs(appId: uint64, ...decoding: T): DecodedLogs { - const transaction = this.groups - .flatMap((g) => g.transactions) + const transaction = this.lastGroup.transactions .filter((t) => t.type === TransactionType.ApplicationCall) .find((t) => asBigInt(t.appId.id) === asBigInt(appId)) let logs = [] diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 675bb0b..99f6335 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -15,7 +15,7 @@ import { payment as itxnPayment, submitGroup as itxnSubmitGroup, } from './impl/inner-transactions' -import { createGlobalState, createLocalState } from './impl/state' +import { Box, BoxMap, BoxRef, GlobalState, LocalState } from './impl/state' import { ContractContext } from './subcontexts/contract-context' import { LedgerContext } from './subcontexts/ledger-context' import { TransactionContext } from './subcontexts/transaction-context' @@ -112,8 +112,11 @@ export class TestExecutionContext implements internal.ExecutionContext { get state() { return { - createGlobalState, - createLocalState, + GlobalState, + LocalState, + Box, + BoxMap, + BoxRef, } } diff --git a/tests/references/box.spec.ts b/tests/references/box.spec.ts new file mode 100644 index 0000000..5f736ef --- /dev/null +++ b/tests/references/box.spec.ts @@ -0,0 +1,101 @@ +import { arc4, BigUint, Box, Bytes, op, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, expect, it, test } from 'vitest' +import { asBytes, toBytes } from '../../src/util' + +class ATestContract extends arc4.Contract { + uint64Box = Box() +} + +const BOX_NOT_CREATED_ERROR = 'Box has not been created' + +describe('Box', () => { + const ctx = new TestExecutionContext() + + afterEach(() => { + ctx.reset() + }) + + it('can be initialised without key', () => { + const contract = ctx.contract.create(ATestContract) + expect(contract.uint64Box.key.toString()).toBe('uint64Box') + }) + + test.for(['key', Bytes('key')])('can be initialised with key %s', (key) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + expect(box.exists).toBe(false) + expect(box.key).toEqual(asBytes(key)) + expect(() => box.value).toThrow(BOX_NOT_CREATED_ERROR) + expect(() => box.length).toThrow(BOX_NOT_CREATED_ERROR) + }) + }) + + // TODO: add tests for settign arc4 types as value + test.for([Uint64(100), Bytes('Test'), 'Test', BigUint(100)])('%s can be set as value', (value) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const key = Bytes('test_key') + const box = Box({ key }) + box.value = value + + const [content, exists] = op.Box.get(key) + const [length, _] = op.Box.length(key) + + expect(exists).toBe(true) + expect(box.length).toEqual(length) + expect(content).toEqual(toBytes(value)) + }) + }) + + // TODO: add tests for settign arc4 types as value + test.for([Uint64(100), Bytes('Test'), 'Test', BigUint(100)])('%s value can be delete', (value) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const key = Bytes('test_key') + const box = Box({ key }) + box.value = value + + box.delete() + + expect(box.exists).toBe(false) + expect(() => box.value).toThrow(BOX_NOT_CREATED_ERROR) + + const [content, exists] = op.Box.get(key) + expect(exists).toBe(false) + expect(content).toEqual(Bytes('')) + }) + }) + + // TODO: add tests for settign arc4 types as value + test.for([Uint64(100), Bytes('Test'), 'Test', BigUint(100)])('can retrieve existing value %s using maybe', (value) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const key = Bytes('test_key') + const box = Box({ key }) + box.value = value + + const [content, exists] = box.maybe() + const [opContent, opExists] = op.Box.get(key) + + expect(exists).toBe(true) + expect(opExists).toBe(true) + expect(opContent).toEqual(toBytes(content)) + }) + }) + + // TODO: add tests for settign arc4 types as value + test.for([Uint64(100), Bytes('Test'), 'Test', BigUint(100)])('can retrieve non-existing value using maybe', (value) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const key = Bytes('test_key') + const box = Box({ key }) + box.value = value + box.delete() + + const [content, exists] = box.maybe() + const [opContent, opExists] = op.Box.get(key) + + expect(exists).toBe(false) + expect(opExists).toBe(false) + expect(opContent).toEqual(Bytes('')) + expect(toBytes(content)).toEqual(Bytes('')) + }) + }) +}) From 9fef4e44d4dc8f8b9ac3c241cb0fb2ce68e406e5 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Wed, 23 Oct 2024 15:39:09 +0800 Subject: [PATCH 37/85] feat: add deferAppCall to transaction contenxt --- src/subcontexts/contract-context.ts | 30 +++++++++++------ src/subcontexts/transaction-context.ts | 32 +++++++++++++++++-- tests/artifacts/box-contract/contract.algo.ts | 23 +++++++++++++ tests/references/box.spec.ts | 19 +++++++++++ 4 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 tests/artifacts/box-contract/contract.algo.ts diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index ae7e589..37f42b8 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -117,6 +117,24 @@ export class ContractContext { return new proxy(...args) } + static createMethodCallTxns( + contract: BaseContract, + method: (...args: TParams) => TReturn, + ...args: TParams + ): Transaction[] { + const abiMetadata = getAbiMetadata(contract, method.name) + const app = lazyContext.ledger.getApplicationForContract(contract) + const { transactions, ...appCallArgs } = extractArraysFromArgs(app, args) + const appTxn = lazyContext.any.txn.applicationCall({ + appId: app, + ...appCallArgs, + // TODO: This needs to be specifiable by the test code + onCompletion: (abiMetadata?.allowActions ?? [])[0], + }) + const txns = [...(transactions ?? []), appTxn] + return txns + } + private isArc4(type: IConstructor): boolean { const proto = Object.getPrototypeOf(type) if (proto === BaseContract) { @@ -158,19 +176,11 @@ export class ContractContext { const isAbiMethod = isArc4 && abiMetadata if (isAbiMethod || isProgramMethod) { return (...args: DeliberateAny[]): DeliberateAny => { - const app = lazyContext.ledger.getApplicationForContract(receiver) - const { transactions, ...appCallArgs } = extractArraysFromArgs(app, args) - const appTxn = lazyContext.any.txn.applicationCall({ - appId: app, - ...appCallArgs, - // TODO: This needs to be specifiable by the test code - onCompletion: (abiMetadata?.allowActions ?? [])[0], - }) - const txns = [...(transactions ?? []), appTxn] + const txns = ContractContext.createMethodCallTxns(receiver, orig as DeliberateAny, ...args) return lazyContext.txn.ensureScope(txns).execute(() => { const returnValue = (orig as DeliberateAny).apply(target, args) if (!isProgramMethod && isAbiMethod && returnValue !== undefined) { - appTxn.logArc4ReturnValue(returnValue) + ;(txns.at(-1) as ApplicationTransaction).logArc4ReturnValue(returnValue) } return returnValue }) diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 5137993..2e382b7 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -1,4 +1,4 @@ -import { bytes, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' +import { bytes, Contract, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' import { lazyContext } from '../context-helpers/internal-context' import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' @@ -24,6 +24,7 @@ import { Transaction, } from '../impl/transactions' import { asBigInt, asNumber, asUint64 } from '../util' +import { ContractContext } from './contract-context' function ScopeGenerator(dispose: () => void) { function* internal() { @@ -46,12 +47,27 @@ interface ExecutionScope { execute: (body: () => TReturn) => TReturn } +export class DeferredAppCall { + constructor( + private readonly appId: uint64, + readonly txns: Transaction[], + private readonly method: (...args: TParams) => TReturn, + private readonly args: TParams, + ) { } + + submit(): TReturn { + // TODO: check_routing_conditions + return this.method(...this.args) + } +} + export class TransactionContext { readonly groups: TransactionGroup[] = [] #activeGroup: TransactionGroup | undefined - createScope(group: Transaction[], activeTransactionIndex?: number): ExecutionScope { - const transactionGroup = new TransactionGroup(group, activeTransactionIndex) + createScope(group: Array>, activeTransactionIndex?: number): ExecutionScope { + const transactions = group.map((t) => t instanceof DeferredAppCall ? t.txns : [t]).flat() + const transactionGroup = new TransactionGroup(transactions, activeTransactionIndex) const previousGroup = this.#activeGroup this.#activeGroup = transactionGroup @@ -108,6 +124,16 @@ export class TransactionContext { activeTransaction.appendLog(value) } + deferAppCall( + contract: Contract, + method: (...args: TParams) => TReturn, + ...args: TParams + ): DeferredAppCall { + const appId = lazyContext.ledger.getApplicationForContract(contract) + const txns = ContractContext.createMethodCallTxns(contract, method, ...args) + return new DeferredAppCall(appId.id, txns, method, args) + } + exportLogs(appId: uint64, ...decoding: T): DecodedLogs { const transaction = this.lastGroup.transactions .filter((t) => t.type === TransactionType.ApplicationCall) diff --git a/tests/artifacts/box-contract/contract.algo.ts b/tests/artifacts/box-contract/contract.algo.ts new file mode 100644 index 0000000..cad8bd4 --- /dev/null +++ b/tests/artifacts/box-contract/contract.algo.ts @@ -0,0 +1,23 @@ +import { arc4, assert, Box, Bytes, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' + +export class BoxContract extends arc4.Contract { + oca = Box() + txn = Box() + + + @arc4.abimethod() + public storeEnums(): void { + this.oca.value = arc4.OnCompleteAction.OptIn + this.txn.value = TransactionType.ApplicationCall + } + + @arc4.abimethod() + public read_enums(): readonly [uint64, uint64] { + assert(op.Box.get(Bytes("oca"))[0] === op.itob(this.oca.value)) + assert(op.Box.get(Bytes("txn"))[0] === op.itob(this.txn.value)) + + return [Uint64(this.oca.value), Uint64(this.txn.value)] + // TODO: use arc4 types when available + // return arc4.Tuple((arc4.UInt64(this.oca.value), arc4.UInt64(this.txn.value))) + } +} diff --git a/tests/references/box.spec.ts b/tests/references/box.spec.ts index 5f736ef..e10588e 100644 --- a/tests/references/box.spec.ts +++ b/tests/references/box.spec.ts @@ -1,7 +1,9 @@ import { arc4, BigUint, Box, Bytes, op, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { itob } from '@algorandfoundation/algorand-typescript/op' import { afterEach, describe, expect, it, test } from 'vitest' import { asBytes, toBytes } from '../../src/util' +import { BoxContract } from '../artifacts/box-contract/contract.algo' class ATestContract extends arc4.Contract { uint64Box = Box() @@ -98,4 +100,21 @@ describe('Box', () => { expect(toBytes(content)).toEqual(Bytes('')) }) }) + + it('can store enum values', () => { + const contract = ctx.contract.create(BoxContract) + + const deferredStoreCall = ctx.txn.deferAppCall(contract, contract.storeEnums) + const deferredReadCall = ctx.txn.deferAppCall(contract, contract.read_enums) + + ctx.txn.createScope([deferredStoreCall, deferredReadCall]).execute(() => { + deferredStoreCall.submit() + const [oca, txn] = deferredReadCall.submit() + + const app = ctx.ledger.getApplicationForContract(contract) + expect(toBytes(ctx.ledger.getBox(app, "oca"))).toEqual(itob(oca)) + expect(toBytes(ctx.ledger.getBox(app, "txn"))).toEqual(itob(txn)) + }) + + }) }) From 97dc9cd01e2f73d00f35c4e5df28db050b4d4554 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Wed, 23 Oct 2024 19:26:59 +0800 Subject: [PATCH 38/85] feat: add more tests for box --- src/impl/box.ts | 24 +- src/impl/state.ts | 94 +++-- src/subcontexts/transaction-context.ts | 4 +- src/util.ts | 8 +- tests/artifacts/box-contract/contract.algo.ts | 5 +- tests/references/box-map.spec.ts | 124 +++++++ tests/references/box-ref.spec.ts | 347 ++++++++++++++++++ tests/references/box.spec.ts | 5 +- 8 files changed, 552 insertions(+), 59 deletions(-) create mode 100644 tests/references/box-map.spec.ts create mode 100644 tests/references/box-ref.spec.ts diff --git a/src/impl/box.ts b/src/impl/box.ts index e1c5fab..d2c12fb 100644 --- a/src/impl/box.ts +++ b/src/impl/box.ts @@ -39,6 +39,9 @@ export const Box: internal.opTypes.BoxType = { throw new internal.errors.InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) + if (boxContent instanceof Uint8Array) { + return toBytes(boxContent.slice(start, start + length)) + } const result = toBytes(boxContent).slice(start, start + length) return result }, @@ -62,7 +65,7 @@ export const Box: internal.opTypes.BoxType = { if (lazyContext.ledger.boxExists(app, name)) { const boxContent = lazyContext.ledger.getBox(app, name) const bytesContent = toBytes(boxContent) - if (bytesContent.length !== newContent.length) { + if (asNumber(bytesContent.length) !== asNumber(newContent.length)) { throw new internal.errors.InternalError('New content length does not match existing box length') } } @@ -100,9 +103,10 @@ export const Box: internal.opTypes.BoxType = { } const boxContent = lazyContext.ledger.getBox(app, name) const bytesContent = toBytes(boxContent) + const size = asNumber(bytesContent.length) let updatedContent - if (newSize > bytesContent.length) { - updatedContent = bytesContent.concat(Bytes(Array(newSize - bytesContent.length).fill(0))) + if (newSize > size) { + updatedContent = bytesContent.concat(Bytes(Array(newSize - size).fill(0))) } else { updatedContent = bytesContent.slice(0, newSize) } @@ -124,17 +128,17 @@ export const Box: internal.opTypes.BoxType = { } const boxContent = lazyContext.ledger.getBox(app, name) const bytesContent = toBytes(boxContent) - if (start > bytesContent.length) { + const size = asNumber(bytesContent.length) + if (start > size) { throw new internal.errors.InternalError('Start index exceeds box size') } - const end = Math.min(start + length, bytesContent.length) + const end = Math.min(start + length, size) let updatedContent = bytesContent.slice(0, start).concat(newContent).concat(bytesContent.slice(end)) - // Adjust the size if necessary - if (updatedContent.length > bytesContent.length) { - updatedContent = updatedContent.slice(0, bytesContent.length) - } else if (updatedContent.length < bytesContent.length) { - updatedContent = updatedContent.concat(Bytes(Array(bytesContent.length - updatedContent.length).fill(0))) + if (updatedContent.length > size) { + updatedContent = updatedContent.slice(0, size) + } else if (updatedContent.length < size) { + updatedContent = updatedContent.concat(Bytes(Array(size - asNumber(updatedContent.length)).fill(0))) } lazyContext.ledger.setBox(app, name, Bytes(updatedContent)) }, diff --git a/src/impl/state.ts b/src/impl/state.ts index f5229f9..b7c69fe 100644 --- a/src/impl/state.ts +++ b/src/impl/state.ts @@ -4,7 +4,6 @@ import { BoxMap as BoxMapType, BoxRef as BoxRefType, Box as BoxType, - Bytes, bytes, GlobalStateOptions, GlobalState as GlobalStateType, @@ -17,7 +16,7 @@ import { import { AccountMap } from '../collections/custom-key-map' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes, asNumber, toBytes } from '../util' +import { asBytes, asBytesCls, asNumber, toBytes } from '../util' export class GlobalStateCls { private readonly _type: string = GlobalStateCls.name @@ -272,7 +271,10 @@ export class BoxRefCls { } get value(): bytes { - return lazyContext.ledger.getBox(this.#app, this.key) + if (!this.exists) { + throw new internal.errors.InternalError('Box has not been created') + } + return toBytes(this.backingValue) } get exists(): boolean { @@ -284,14 +286,14 @@ export class BoxRefCls { if (size > MAX_BOX_SIZE) { throw new internal.errors.InternalError(`Box size cannot exceed ${MAX_BOX_SIZE}`) } - const [content, exists] = this.maybe() - if (exists && content.length !== size) { + const content = this.backingValue + if (this.exists && content.length !== size) { throw new internal.errors.InternalError('Box already exists with a different size') } - if (exists) { + if (this.exists) { return false } - lazyContext.ledger.setBox(this.#app, this.key, Bytes(Array(size).fill(0))) + this.backingValue = new Uint8Array(Array(size).fill(0)) return true } @@ -301,12 +303,12 @@ export class BoxRefCls { } put(value: internal.primitives.StubBytesCompat): void { - const bytesValue = asBytes(value) - const [content, exists] = this.maybe() - if (exists && content.length !== bytesValue.length) { + const bytesValue = asBytesCls(value) + const content = this.backingValue + if (this.exists && content.length !== bytesValue.length.asNumber()) { throw new internal.errors.InternalError('Box already exists with a different size') } - lazyContext.ledger.setBox(this.#app, this.key, bytesValue) + this.backingValue = bytesValue.asUint8Array() } splice( @@ -314,55 +316,56 @@ export class BoxRefCls { length: internal.primitives.StubUint64Compat, value: internal.primitives.StubBytesCompat, ): void { - const [content, exists] = this.maybe() + const content = this.backingValue const startNumber = asNumber(start) const lengthNumber = asNumber(length) - const valueBytes = asBytes(value) - if (!exists) { + const valueBytes = asBytesCls(value) + if (!this.exists) { throw new internal.errors.InternalError('Box has not been created') } if (startNumber > content.length) { throw new internal.errors.InternalError('Start index exceeds box size') } const end = Math.min(startNumber + lengthNumber, content.length) - let updatedContent = content.slice(0, startNumber).concat(valueBytes).concat(content.slice(end)) + let updatedContent = this.concat(content.slice(0, startNumber), valueBytes.asUint8Array(), content.slice(end)) if (updatedContent.length > content.length) { updatedContent = updatedContent.slice(0, content.length) } else if (updatedContent.length < content.length) { - updatedContent = updatedContent.concat(Bytes(Array(content.length - updatedContent.length).fill(0))) + updatedContent = this.concat(updatedContent, new Uint8Array(Array(content.length - updatedContent.length).fill(0))) } - lazyContext.ledger.setBox(this.#app, this.key, updatedContent) + this.backingValue = updatedContent } replace(start: internal.primitives.StubUint64Compat, value: internal.primitives.StubBytesCompat): void { - const [content, exists] = this.maybe() + const content = this.backingValue const startNumber = asNumber(start) - const valueBytes = asBytes(value) - if (!exists) { + const valueBytes = asBytesCls(value) + if (!this.exists) { throw new internal.errors.InternalError('Box has not been created') } - if (startNumber + valueBytes.length > content.length) { + if (startNumber + asNumber(valueBytes.length) > content.length) { throw new internal.errors.InternalError('Replacement content exceeds box size') } - const updatedContent = content - .slice(0, startNumber) - .concat(valueBytes) - .concat(content.slice(startNumber + valueBytes.length)) - lazyContext.ledger.setBox(this.#app, this.key, updatedContent) + const updatedContent = this.concat( + content.slice(0, startNumber), + valueBytes.asUint8Array(), + content.slice(startNumber + valueBytes.length.asNumber()), + ) + this.backingValue = updatedContent } extract(start: internal.primitives.StubUint64Compat, length: internal.primitives.StubUint64Compat): bytes { - const [content, exists] = this.maybe() + const content = this.backingValue const startNumber = asNumber(start) const lengthNumber = asNumber(length) - if (!exists) { + if (!this.exists) { throw new internal.errors.InternalError('Box has not been created') } if (startNumber + lengthNumber > content.length) { throw new internal.errors.InternalError('Index out of bounds') } - return content.slice(startNumber, startNumber + lengthNumber) + return toBytes(content.slice(startNumber, startNumber + lengthNumber)) } delete(): boolean { return lazyContext.ledger.deleteBox(this.#app, this.key) @@ -373,29 +376,46 @@ export class BoxRefCls { if (newSizeNumber > MAX_BOX_SIZE) { throw new internal.errors.InternalError(`Box size cannot exceed ${MAX_BOX_SIZE}`) } - const [content, exists] = this.maybe() - if (!exists) { + const content = this.backingValue + if (!this.exists) { throw new internal.errors.InternalError('Box has not been created') } let updatedContent if (newSizeNumber > content.length) { - updatedContent = content.concat(Bytes(Array(newSizeNumber - content.length).fill(0))) + updatedContent = this.concat(content, new Uint8Array(Array(newSizeNumber - content.length).fill(0))) } else { updatedContent = content.slice(0, newSize) } - lazyContext.ledger.setBox(this.#app, this.key, updatedContent) + this.backingValue = updatedContent } maybe(): readonly [bytes, boolean] { - return [lazyContext.ledger.getBox(this.#app, this.key), lazyContext.ledger.boxExists(this.#app, this.key)] + return [asBytes(lazyContext.ledger.getBox(this.#app, this.key)), lazyContext.ledger.boxExists(this.#app, this.key)] } get length(): uint64 { - const [value, exists] = this.maybe() - if (!exists) { + if (!this.exists) { throw new internal.errors.InternalError('Box has not been created') } - return value.length + return this.backingValue.length + } + + private get backingValue(): Uint8Array { + return lazyContext.ledger.getBox(this.#app, this.key) + } + + private set backingValue(value: Uint8Array) { + lazyContext.ledger.setBox(this.#app, this.key, value) + } + + private concat(...values: Uint8Array[]): Uint8Array { + const result = new Uint8Array(values.reduce((acc, value) => acc + value.length, 0)) + let index = 0 + for (const value of values) { + result.set(value, index) + index += value.length + } + return result } } diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 2e382b7..56722ef 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -53,7 +53,7 @@ export class DeferredAppCall { readonly txns: Transaction[], private readonly method: (...args: TParams) => TReturn, private readonly args: TParams, - ) { } + ) {} submit(): TReturn { // TODO: check_routing_conditions @@ -66,7 +66,7 @@ export class TransactionContext { #activeGroup: TransactionGroup | undefined createScope(group: Array>, activeTransactionIndex?: number): ExecutionScope { - const transactions = group.map((t) => t instanceof DeferredAppCall ? t.txns : [t]).flat() + const transactions = group.map((t) => (t instanceof DeferredAppCall ? t.txns : [t])).flat() const transactionGroup = new TransactionGroup(transactions, activeTransactionIndex) const previousGroup = this.#activeGroup this.#activeGroup = transactionGroup diff --git a/src/util.ts b/src/util.ts index 03d5fc6..5705f33 100644 --- a/src/util.ts +++ b/src/util.ts @@ -49,14 +49,14 @@ export const toBytes = (val: unknown): bytes => { if (uint64Val !== undefined) { return uint64Val.toBytes().asAlgoTs() } - const bigUintVal = asMaybeBigUintCls(val) - if (bigUintVal !== undefined) { - return bigUintVal.toBytes().asAlgoTs() - } const bytesVal = asMaybeBytesCls(val) if (bytesVal !== undefined) { return bytesVal.asAlgoTs() } + const bigUintVal = asMaybeBigUintCls(val) + if (bigUintVal !== undefined) { + return bigUintVal.toBytes().asAlgoTs() + } if (val instanceof BytesBackedCls) { return val.bytes } diff --git a/tests/artifacts/box-contract/contract.algo.ts b/tests/artifacts/box-contract/contract.algo.ts index cad8bd4..b85e8be 100644 --- a/tests/artifacts/box-contract/contract.algo.ts +++ b/tests/artifacts/box-contract/contract.algo.ts @@ -4,7 +4,6 @@ export class BoxContract extends arc4.Contract { oca = Box() txn = Box() - @arc4.abimethod() public storeEnums(): void { this.oca.value = arc4.OnCompleteAction.OptIn @@ -13,8 +12,8 @@ export class BoxContract extends arc4.Contract { @arc4.abimethod() public read_enums(): readonly [uint64, uint64] { - assert(op.Box.get(Bytes("oca"))[0] === op.itob(this.oca.value)) - assert(op.Box.get(Bytes("txn"))[0] === op.itob(this.txn.value)) + assert(op.Box.get(Bytes('oca'))[0] === op.itob(this.oca.value)) + assert(op.Box.get(Bytes('txn'))[0] === op.itob(this.txn.value)) return [Uint64(this.oca.value), Uint64(this.txn.value)] // TODO: use arc4 types when available diff --git a/tests/references/box-map.spec.ts b/tests/references/box-map.spec.ts new file mode 100644 index 0000000..1acc0a6 --- /dev/null +++ b/tests/references/box-map.spec.ts @@ -0,0 +1,124 @@ +import { arc4, BigUint, BoxMap, Bytes, bytes, op, Uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, expect, it, test } from 'vitest' +import { asBytes, toBytes } from '../../src/util' + +class ATestContract extends arc4.Contract { + uint64BoxMap = BoxMap() +} + +const BOX_NOT_CREATED_ERROR = 'Box has not been created' + +describe('BoxMap', () => { + const ctx = new TestExecutionContext() + + afterEach(() => { + ctx.reset() + }) + + it('can be initialised without key', () => { + const contract = ctx.contract.create(ATestContract) + expect(contract.uint64BoxMap.keyPrefix.toString()).toBe('uint64BoxMap') + }) + + test.for(['key_prefix', Bytes('key_prefix')])('can be initialised with key prefix %s', (keyPrefix) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxMap({ keyPrefix }) + + 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) + }) + }) + + // TODO: add tests for settign arc4 types as value + test.for([ + [Bytes('abc'), Uint64(100)], + ['def', Bytes('Test')], + [BigUint(123), 'Test'], + ])('key %s and value %s can be set as value', ([key, value]) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const keyPrefix = Bytes('test_key_prefix') + const box = BoxMap({ keyPrefix }) + box.set(key, value) + + const boxContent = box.get(key) + const fullKey = keyPrefix.concat(toBytes(key)) + + const [opBoxContent, opExists] = op.Box.get(fullKey) + const [opLength, _] = op.Box.length(fullKey) + + expect(opExists).toBe(true) + expect(box.length(key)).toEqual(opLength) + expect(toBytes(boxContent)).toEqual(opBoxContent) + }) + }) + + // TODO: add tests for settign arc4 types as value + test.for([ + [Bytes('abc'), Uint64(100)], + ['def', Bytes('Test')], + [BigUint(123), 'Test'], + ])('key %s and value %s can be delete', ([key, value]) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const keyPrefix = Bytes('test_key_prefix') + const box = BoxMap({ keyPrefix }) + box.set(key, value) + + box.delete(key) + + expect(() => box.get(key)).toThrow(BOX_NOT_CREATED_ERROR) + const fullKey = keyPrefix.concat(toBytes(key)) + const [opBoxContent, opExists] = op.Box.get(fullKey) + expect(opExists).toBe(false) + expect(opBoxContent).toEqual(Bytes('')) + }) + }) + + // TODO: add tests for settign arc4 types as value + test.for([ + [Bytes('abc'), Uint64(100)], + ['def', Bytes('Test')], + [BigUint(123), 'Test'], + ])('can retrieve existing key %s and value %s using maybe', ([key, value]) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const keyPrefix = Bytes('test_key_prefix') + const box = BoxMap({ keyPrefix }) + box.set(key, value) + + const [content, exists] = box.maybe(key) + + const fullKey = keyPrefix.concat(toBytes(key)) + const [opContent, opExists] = op.Box.get(fullKey) + const [opLength, _] = op.Box.length(fullKey) + + expect(exists).toBe(true) + expect(opExists).toBe(true) + expect(box.length(key)).toEqual(opLength) + expect(toBytes(content)).toEqual(opContent) + }) + }) + test.for([ + [Bytes('abc'), Uint64(100)], + ['def', Bytes('Test')], + [BigUint(123), 'Test'], + ])('can retrieve non-existing value using maybe', ([key, value]) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const keyPrefix = Bytes('test_key_prefix') + const box = BoxMap({ keyPrefix }) + box.set(key, value) + box.delete(key) + + const [content, exists] = box.maybe(key) + + expect(exists).toBe(false) + expect(toBytes(content)).toEqual(Bytes('')) + + const fullKey = keyPrefix.concat(toBytes(key)) + const [opContent, opExists] = op.Box.get(fullKey) + expect(opExists).toBe(false) + expect(opContent).toEqual(Bytes('')) + }) + }) +}) diff --git a/tests/references/box-ref.spec.ts b/tests/references/box-ref.spec.ts new file mode 100644 index 0000000..8511ce4 --- /dev/null +++ b/tests/references/box-ref.spec.ts @@ -0,0 +1,347 @@ +import { arc4, BoxRef, Bytes, op } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, expect, it, test } from 'vitest' +import { MAX_BOX_SIZE, MAX_BYTES_SIZE } from '../../src/constants' +import { asBytes, asNumber, asUint64 } from '../../src/util' + +class ATestContract extends arc4.Contract { + uint64BoxRef = BoxRef() +} + +const TEST_BOX_KEY = 'test_key' +const BOX_NOT_CREATED_ERROR = 'Box has not been created' + +describe('BoxRef', () => { + const ctx = new TestExecutionContext() + + afterEach(() => { + ctx.reset() + }) + + it('can be initialised without key', () => { + const contract = ctx.contract.create(ATestContract) + expect(contract.uint64BoxRef.key.toString()).toBe('uint64BoxRef') + }) + + test.each(['key', Bytes('key')])('can be initialised with key %s', (key) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key }) + expect(box.exists).toBe(false) + expect(box.key).toEqual(asBytes(key)) + expect(() => box.value).toThrow(BOX_NOT_CREATED_ERROR) + expect(() => box.length).toThrow(BOX_NOT_CREATED_ERROR) + }) + }) + + test.each([0, 1, 10, MAX_BOX_SIZE])('can create a box of size %s', (size) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size }) + + expect(box.length).toBe(size) + + assertBoxValue(box, new Uint8Array(Array(size).fill(0))) + }) + }) + + it(`throws error when creating a box with size greater than ${MAX_BOX_SIZE}`, () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + expect(() => box.create({ size: MAX_BOX_SIZE + 1 })).toThrow(`Box size cannot exceed ${MAX_BOX_SIZE}`) + }) + }) + + it('can delete value', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size: MAX_BOX_SIZE }) + + expect(box.length).toBe(MAX_BOX_SIZE) + + const existed = box.delete() + + expect(existed).toBe(true) + expect(box.exists).toBe(false) + + expect(() => box.length).toThrow(BOX_NOT_CREATED_ERROR) + expect(() => box.resize(10)).toThrow(BOX_NOT_CREATED_ERROR) + expect(() => box.replace(0, Bytes(0x11))).toThrow(BOX_NOT_CREATED_ERROR) + + expect(box.delete()).toBe(false) + }) + }) + + test.each([ + [1, 0], + [10, 1], + [MAX_BOX_SIZE, 10], + [MAX_BOX_SIZE, MAX_BYTES_SIZE], + ])('can resize to smaller size from %s to %s', (size, newSize) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size }) + initialiseBoxValue(box, new Uint8Array(Array(size).fill(0x11))) + + box.resize(newSize) + expect(box.length).toBe(newSize) + assertBoxValue(box, new Uint8Array(Array(newSize).fill(0x11))) + }) + }) + + test.each([ + [0, 1], + [1, 10], + [10, MAX_BYTES_SIZE], + [MAX_BYTES_SIZE, MAX_BOX_SIZE], + ])('can resize to larger size from %s to %s', (size, newSize) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size }) + initialiseBoxValue(box, new Uint8Array(Array(size).fill(0x11))) + + box.resize(newSize) + expect(box.length).toBe(newSize) + assertBoxValue( + box, + new Uint8Array( + Array(size) + .fill(0x11) + .concat(Array(newSize - size).fill(0x00)), + ), + ) + }) + }) + + it(`throws error when resizing to size greater than ${MAX_BOX_SIZE}`, () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size: 10 }) + + expect(() => box.resize(MAX_BOX_SIZE + 1)).toThrow(`Box size cannot exceed ${MAX_BOX_SIZE}`) + }) + }) + + it('can replace value', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size: MAX_BOX_SIZE }) + + const boxValue = new Uint8Array( + Array(MAX_BOX_SIZE / 2) + .fill([0x01, 0x02]) + .flat(), + ) + + initialiseBoxValue(box, boxValue) + + assertBoxValue(box, boxValue) + }) + }) + + it('throws error when replacing value of a non-existing box', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + + expect(() => box.replace(0, Bytes(0x11))).toThrow(BOX_NOT_CREATED_ERROR) + }) + }) + + test.each([ + [0, Bytes(new Uint8Array(Array(11).fill(0x11)))], + [10, Bytes(new Uint8Array([0x11]))], + [9, Bytes(new Uint8Array(Array(2).fill(0x11)))], + ])('throws error when replacing with a value that exceeds box size', (start, replacement) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size: 10 }) + + expect(() => box.replace(asUint64(start), replacement)).toThrow('Replacement content exceeds box size') + }) + }) + + it('can retrieve value using maybe', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size: 10 }) + + const boxValue = new Uint8Array(Array(5).fill([0x01, 0x02]).flat()) + box.put(Bytes(boxValue)) + + const [value, exists] = box.maybe() + const [opValue, opExists] = op.Box.get(box.key) + expect(exists).toBe(true) + expect(opExists).toBe(true) + expect(value).toEqual(Bytes(boxValue)) + expect(opValue).toEqual(Bytes(boxValue)) + }) + }) + + it('can retrieve non-existing value using maybe', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size: 10 }) + + const boxValue = new Uint8Array(Array(5).fill([0x01, 0x02]).flat()) + box.put(Bytes(boxValue)) + box.delete() + + const [value, exists] = box.maybe() + const [opValue, opExists] = op.Box.get(box.key) + expect(exists).toBe(false) + expect(opExists).toBe(false) + expect(value).toEqual(Bytes('')) + expect(opValue).toEqual(Bytes('')) + }) + }) + + test.each([ + [0, Bytes('')], + [10, Bytes(new Uint8Array(Array(10).fill(0x11)))], + [MAX_BYTES_SIZE, Bytes(new Uint8Array(Array(MAX_BYTES_SIZE).fill(0x11)))], + ])('can put and get value', (size, value) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size }) + + box.put(value) + + const content = box.get({ default: Bytes(new Uint8Array(Array(size).fill(0x00))) }) + expect(content).toEqual(value) + + const [opContent, opExists] = op.Box.get(box.key) + expect(opExists).toBe(true) + expect(opContent).toEqual(value) + }) + }) + + it('can put value when box is not created', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + + const boxValue = new Uint8Array(Array(5).fill([0x01, 0x02]).flat()) + box.put(Bytes(boxValue)) + + expect(box.exists).toBe(true) + expect(box.length).toBe(10) + + const content = box.get({ default: Bytes(new Uint8Array(Array(10).fill(0x00))) }) + expect(content).toEqual(Bytes(boxValue)) + }) + }) + + it('can get value with default value when box is not created', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + + const defaultValue = Bytes(new Uint8Array(Array(10).fill(0x00))) + const content = box.get({ default: defaultValue }) + expect(content).toEqual(defaultValue) + }) + }) + + it('throws error when put and get value exceeding max bytes size', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size: MAX_BOX_SIZE }) + + expect(() => box.put(Bytes(new Uint8Array(Array(MAX_BOX_SIZE).fill(0x11))))).toThrow('exceeds maximum length') + expect(() => box.get({ default: Bytes(new Uint8Array(Array(MAX_BOX_SIZE).fill(0x11))) })).toThrow('exceeds maximum length') + }) + }) + + it('can splice with longer value', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const size = 10 + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size: size }) + + const boxValue = new Uint8Array(Array(5).fill([0x01, 0x02]).flat()) + box.put(Bytes(boxValue)) + + const replacement = new Uint8Array(Array(2).fill(0x11)) + box.splice(1, 1, Bytes(replacement)) + + const content = box.get({ default: Bytes(new Uint8Array(Array(size).fill(0x00))) }) + + const opBoxKey = asBytes('another_key') + op.Box.create(opBoxKey, size) + op.Box.put(opBoxKey, Bytes(boxValue)) + op.Box.splice(opBoxKey, 1, 1, Bytes(replacement)) + const [opBoxContent, _opBoxExists] = op.Box.get(opBoxKey) + const [opBoxLength, _] = op.Box.length(opBoxKey) + + expect(content).toEqual(Bytes(new Uint8Array([0x01, ...replacement, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01]))) + expect(content).toEqual(opBoxContent) + expect(box.length).toEqual(size) + expect(box.length).toEqual(asNumber(opBoxLength)) + }) + }) + + it('can splice with shorter value', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const size = 10 + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size: size }) + + const boxValue = new Uint8Array(Array(5).fill([0x01, 0x02]).flat()) + box.put(Bytes(boxValue)) + + const replacement = new Uint8Array(Array(2).fill(0x11)) + box.splice(1, 5, Bytes(replacement)) + + const content = box.get({ default: Bytes(new Uint8Array(Array(size).fill(0x00))) }) + + const opBoxKey = asBytes('another_key') + op.Box.create(opBoxKey, size) + op.Box.put(opBoxKey, Bytes(boxValue)) + op.Box.splice(opBoxKey, 1, 5, Bytes(replacement)) + const [opBoxContent, _opBoxExists] = op.Box.get(opBoxKey) + const [opBoxLength, _] = op.Box.length(opBoxKey) + + expect(content).toEqual(Bytes(new Uint8Array([0x01, ...replacement, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00]))) + expect(content).toEqual(opBoxContent) + expect(box.length).toEqual(size) + expect(box.length).toEqual(asNumber(opBoxLength)) + }) + }) + + it('can splice when box does not exist', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + + expect(() => box.splice(1, 1, Bytes(new Uint8Array([0x11])))).toThrow(BOX_NOT_CREATED_ERROR) + }) + }) + + it('throws error when splicing with index out of bounds', () => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = BoxRef({ key: TEST_BOX_KEY }) + box.create({ size: 10 }) + + expect(() => box.splice(11, 1, Bytes(new Uint8Array([0x11])))).toThrow('Start index exceeds box size') + }) + }) +}) + +const initialiseBoxValue = (box: BoxRef, value: Uint8Array): void => { + let index = 0 + const size = asNumber(value.length) + while (index < size) { + const length = Math.min(size - index, MAX_BYTES_SIZE) + box.replace(index, Bytes(value.slice(index, index + length))) + index += length + } +} + +const assertBoxValue = (box: BoxRef, expectedValue: Uint8Array, start: number = 0): void => { + let index = start + const size = expectedValue.length + while (index < size) { + const length = Math.min(size - index, MAX_BYTES_SIZE) + const boxContent = box.extract(index, length) + const opBoxContent = op.Box.extract(box.key, index, length) + expect(boxContent).toEqual(opBoxContent) + expect(boxContent).toEqual(Bytes(expectedValue.slice(index, index + length))) + index += length + } +} diff --git a/tests/references/box.spec.ts b/tests/references/box.spec.ts index e10588e..333d280 100644 --- a/tests/references/box.spec.ts +++ b/tests/references/box.spec.ts @@ -112,9 +112,8 @@ describe('Box', () => { const [oca, txn] = deferredReadCall.submit() const app = ctx.ledger.getApplicationForContract(contract) - expect(toBytes(ctx.ledger.getBox(app, "oca"))).toEqual(itob(oca)) - expect(toBytes(ctx.ledger.getBox(app, "txn"))).toEqual(itob(txn)) + expect(toBytes(ctx.ledger.getBox(app, 'oca'))).toEqual(itob(oca)) + expect(toBytes(ctx.ledger.getBox(app, 'txn'))).toEqual(itob(txn)) }) - }) }) From 9bc9ab1d76c3f0e9c8d15250a50408abfb9182da Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 24 Oct 2024 14:17:18 +0800 Subject: [PATCH 39/85] refactor: make sure box op code works with boxes larger than max bytes size --- src/impl/box.ts | 81 +++++++++---------- src/impl/state.ts | 36 ++++----- src/util.ts | 10 +++ tests/artifacts/box-contract/contract.algo.ts | 4 +- tests/references/box-map.spec.ts | 13 +-- tests/references/box-ref.spec.ts | 11 +-- tests/references/box.spec.ts | 11 +-- 7 files changed, 70 insertions(+), 96 deletions(-) diff --git a/src/impl/box.ts b/src/impl/box.ts index d2c12fb..af6607d 100644 --- a/src/impl/box.ts +++ b/src/impl/box.ts @@ -1,10 +1,10 @@ -import { Bytes, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes, asNumber, toBytes } from '../util' +import { asBytes, asBytesCls, asNumber, conactUint8Arrays, toBytes } from '../util' export const Box: internal.opTypes.BoxType = { - create: function (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): boolean { + create(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): boolean { const name = asBytes(a) const size = asNumber(b) if (name.length === 0 || size > MAX_BOX_SIZE) { @@ -14,10 +14,10 @@ export const Box: internal.opTypes.BoxType = { if (lazyContext.ledger.boxExists(app, name)) { return false } - lazyContext.ledger.setBox(app, name, Bytes(Array(size).fill(0))) + lazyContext.ledger.setBox(app, name, new Uint8Array(Array(size).fill(0))) return true }, - delete: function (a: internal.primitives.StubBytesCompat): boolean { + delete(a: internal.primitives.StubBytesCompat): boolean { const name = asBytes(a) const app = lazyContext.activeApplication if (!lazyContext.ledger.boxExists(app, name)) { @@ -26,11 +26,7 @@ export const Box: internal.opTypes.BoxType = { lazyContext.ledger.deleteBox(app, name) return true }, - extract: function ( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubUint64Compat, - ): bytes { + extract(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat, c: internal.primitives.StubUint64Compat): bytes { const name = asBytes(a) const start = asNumber(b) const length = asNumber(c) @@ -45,56 +41,57 @@ export const Box: internal.opTypes.BoxType = { const result = toBytes(boxContent).slice(start, start + length) return result }, - get: function (a: internal.primitives.StubBytesCompat): readonly [bytes, boolean] { + get(a: internal.primitives.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: function (a: internal.primitives.StubBytesCompat): readonly [uint64, boolean] { + length(a: internal.primitives.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) + if (boxContent instanceof Uint8Array) { + return [boxContent.length, exists] + } const bytesContent = toBytes(boxContent) - return [bytesContent.length, lazyContext.ledger.boxExists(app, name)] + return [bytesContent.length, exists] }, - put: function (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubBytesCompat): void { + put(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubBytesCompat): void { const name = asBytes(a) const app = lazyContext.activeApplication const newContent = asBytes(b) if (lazyContext.ledger.boxExists(app, name)) { const boxContent = lazyContext.ledger.getBox(app, name) - const bytesContent = toBytes(boxContent) - if (asNumber(bytesContent.length) !== asNumber(newContent.length)) { + const length = boxContent instanceof Uint8Array ? boxContent.length : toBytes(boxContent).length + if (asNumber(length) !== asNumber(newContent.length)) { throw new internal.errors.InternalError('New content length does not match existing box length') } } lazyContext.ledger.setBox(app, name, newContent) }, - replace: function ( - a: internal.primitives.StubBytesCompat, - b: internal.primitives.StubUint64Compat, - c: internal.primitives.StubBytesCompat, - ): void { + replace(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat, c: internal.primitives.StubBytesCompat): void { const name = asBytes(a) const start = asNumber(b) - const newContent = asBytes(c) + const newContent = asBytesCls(c).asUint8Array() const app = lazyContext.activeApplication if (!lazyContext.ledger.boxExists(app, name)) { throw new internal.errors.InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) - const bytesContent = toBytes(boxContent) - if (start + newContent.length > bytesContent.length) { + const uint8ArrayContent = boxContent instanceof Uint8Array ? boxContent : asBytesCls(toBytes(boxContent)).asUint8Array() + if (start + newContent.length > uint8ArrayContent.length) { throw new internal.errors.InternalError('Replacement content exceeds box size') } - const updatedContent = bytesContent - .slice(0, start) - .concat(newContent) - .concat(bytesContent.slice(start + newContent.length)) - lazyContext.ledger.setBox(app, name, Bytes(updatedContent)) + const updatedContent = conactUint8Arrays( + uint8ArrayContent.slice(0, start), + newContent, + uint8ArrayContent.slice(start + newContent.length), + ) + lazyContext.ledger.setBox(app, name, updatedContent) }, - resize: function (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): void { + resize(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): void { const name = asBytes(a) const newSize = asNumber(b) const app = lazyContext.activeApplication @@ -102,17 +99,17 @@ export const Box: internal.opTypes.BoxType = { throw new internal.errors.InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) - const bytesContent = toBytes(boxContent) - const size = asNumber(bytesContent.length) + const uint8ArrayContent = boxContent instanceof Uint8Array ? boxContent : asBytesCls(toBytes(boxContent)).asUint8Array() + const size = uint8ArrayContent.length let updatedContent if (newSize > size) { - updatedContent = bytesContent.concat(Bytes(Array(newSize - size).fill(0))) + updatedContent = conactUint8Arrays(uint8ArrayContent, new Uint8Array(Array(newSize - size).fill(0))) } else { - updatedContent = bytesContent.slice(0, newSize) + updatedContent = uint8ArrayContent.slice(0, newSize) } - lazyContext.ledger.setBox(app, name, Bytes(updatedContent)) + lazyContext.ledger.setBox(app, name, updatedContent) }, - splice: function ( + splice( a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat, c: internal.primitives.StubUint64Compat, @@ -121,25 +118,25 @@ export const Box: internal.opTypes.BoxType = { const name = asBytes(a) const start = asNumber(b) const length = asNumber(c) - const newContent = asBytes(d) + const newContent = asBytesCls(d).asUint8Array() const app = lazyContext.activeApplication if (!lazyContext.ledger.boxExists(app, name)) { throw new internal.errors.InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) - const bytesContent = toBytes(boxContent) - const size = asNumber(bytesContent.length) + const uint8ArrayContent = boxContent instanceof Uint8Array ? boxContent : asBytesCls(toBytes(boxContent)).asUint8Array() + const size = uint8ArrayContent.length if (start > size) { throw new internal.errors.InternalError('Start index exceeds box size') } const end = Math.min(start + length, size) - let updatedContent = bytesContent.slice(0, start).concat(newContent).concat(bytesContent.slice(end)) + let updatedContent = conactUint8Arrays(uint8ArrayContent.slice(0, start), newContent, uint8ArrayContent.slice(end)) // Adjust the size if necessary if (updatedContent.length > size) { updatedContent = updatedContent.slice(0, size) } else if (updatedContent.length < size) { - updatedContent = updatedContent.concat(Bytes(Array(size - asNumber(updatedContent.length)).fill(0))) + updatedContent = conactUint8Arrays(updatedContent, new Uint8Array(Array(size - asNumber(updatedContent.length)).fill(0))) } - lazyContext.ledger.setBox(app, name, Bytes(updatedContent)) + lazyContext.ledger.setBox(app, name, updatedContent) }, } diff --git a/src/impl/state.ts b/src/impl/state.ts index b7c69fe..63d1b32 100644 --- a/src/impl/state.ts +++ b/src/impl/state.ts @@ -16,7 +16,7 @@ import { import { AccountMap } from '../collections/custom-key-map' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes, asBytesCls, asNumber, toBytes } from '../util' +import { asBytes, asBytesCls, asNumber, conactUint8Arrays, toBytes } from '../util' export class GlobalStateCls { private readonly _type: string = GlobalStateCls.name @@ -277,6 +277,15 @@ export class BoxRefCls { return toBytes(this.backingValue) } + set value(v: internal.primitives.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') + } + this.backingValue = bytesValue.asUint8Array() + } + get exists(): boolean { return lazyContext.ledger.boxExists(this.#app, this.key) } @@ -303,12 +312,7 @@ export class BoxRefCls { } put(value: internal.primitives.StubBytesCompat): void { - const bytesValue = asBytesCls(value) - const content = this.backingValue - if (this.exists && content.length !== bytesValue.length.asNumber()) { - throw new internal.errors.InternalError('Box already exists with a different size') - } - this.backingValue = bytesValue.asUint8Array() + this.value = value } splice( @@ -327,12 +331,12 @@ export class BoxRefCls { throw new internal.errors.InternalError('Start index exceeds box size') } const end = Math.min(startNumber + lengthNumber, content.length) - let updatedContent = this.concat(content.slice(0, startNumber), valueBytes.asUint8Array(), content.slice(end)) + let updatedContent = conactUint8Arrays(content.slice(0, startNumber), valueBytes.asUint8Array(), content.slice(end)) if (updatedContent.length > content.length) { updatedContent = updatedContent.slice(0, content.length) } else if (updatedContent.length < content.length) { - updatedContent = this.concat(updatedContent, new Uint8Array(Array(content.length - updatedContent.length).fill(0))) + updatedContent = conactUint8Arrays(updatedContent, new Uint8Array(Array(content.length - updatedContent.length).fill(0))) } this.backingValue = updatedContent } @@ -347,7 +351,7 @@ export class BoxRefCls { if (startNumber + asNumber(valueBytes.length) > content.length) { throw new internal.errors.InternalError('Replacement content exceeds box size') } - const updatedContent = this.concat( + const updatedContent = conactUint8Arrays( content.slice(0, startNumber), valueBytes.asUint8Array(), content.slice(startNumber + valueBytes.length.asNumber()), @@ -382,7 +386,7 @@ export class BoxRefCls { } let updatedContent if (newSizeNumber > content.length) { - updatedContent = this.concat(content, new Uint8Array(Array(newSizeNumber - content.length).fill(0))) + updatedContent = conactUint8Arrays(content, new Uint8Array(Array(newSizeNumber - content.length).fill(0))) } else { updatedContent = content.slice(0, newSize) } @@ -407,16 +411,6 @@ export class BoxRefCls { private set backingValue(value: Uint8Array) { lazyContext.ledger.setBox(this.#app, this.key, value) } - - private concat(...values: Uint8Array[]): Uint8Array { - const result = new Uint8Array(values.reduce((acc, value) => acc + value.length, 0)) - let index = 0 - for (const value of values) { - result.set(value, index) - index += value.length - } - return result - } } export function Box(options?: { key: bytes | string }): BoxType { diff --git a/src/util.ts b/src/util.ts index 5705f33..f56d316 100644 --- a/src/util.ts +++ b/src/util.ts @@ -180,3 +180,13 @@ export const combineIntoMaxBytePages = (pages: bytes[]): bytes[] => { } return result } + +export const conactUint8Arrays = (...values: Uint8Array[]): Uint8Array => { + const result = new Uint8Array(values.reduce((acc, value) => acc + value.length, 0)) + let index = 0 + for (const value of values) { + result.set(value, index) + index += value.length + } + return result +} diff --git a/tests/artifacts/box-contract/contract.algo.ts b/tests/artifacts/box-contract/contract.algo.ts index b85e8be..1bcdff8 100644 --- a/tests/artifacts/box-contract/contract.algo.ts +++ b/tests/artifacts/box-contract/contract.algo.ts @@ -1,8 +1,8 @@ import { arc4, assert, Box, Bytes, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' export class BoxContract extends arc4.Contract { - oca = Box() - txn = Box() + oca = Box({ key: Bytes('oca') }) + txn = Box({ key: Bytes('txn') }) @arc4.abimethod() public storeEnums(): void { diff --git a/tests/references/box-map.spec.ts b/tests/references/box-map.spec.ts index 1acc0a6..9f8272e 100644 --- a/tests/references/box-map.spec.ts +++ b/tests/references/box-map.spec.ts @@ -1,12 +1,8 @@ -import { arc4, BigUint, BoxMap, Bytes, bytes, op, Uint64 } from '@algorandfoundation/algorand-typescript' +import { BigUint, BoxMap, Bytes, bytes, op, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import { afterEach, describe, expect, it, test } from 'vitest' +import { afterEach, describe, expect, test } from 'vitest' import { asBytes, toBytes } from '../../src/util' -class ATestContract extends arc4.Contract { - uint64BoxMap = BoxMap() -} - const BOX_NOT_CREATED_ERROR = 'Box has not been created' describe('BoxMap', () => { @@ -16,11 +12,6 @@ describe('BoxMap', () => { ctx.reset() }) - it('can be initialised without key', () => { - const contract = ctx.contract.create(ATestContract) - expect(contract.uint64BoxMap.keyPrefix.toString()).toBe('uint64BoxMap') - }) - test.for(['key_prefix', Bytes('key_prefix')])('can be initialised with key prefix %s', (keyPrefix) => { ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { const box = BoxMap({ keyPrefix }) diff --git a/tests/references/box-ref.spec.ts b/tests/references/box-ref.spec.ts index 8511ce4..4ee7bcf 100644 --- a/tests/references/box-ref.spec.ts +++ b/tests/references/box-ref.spec.ts @@ -1,13 +1,9 @@ -import { arc4, BoxRef, Bytes, op } from '@algorandfoundation/algorand-typescript' +import { BoxRef, Bytes, op } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, it, test } from 'vitest' import { MAX_BOX_SIZE, MAX_BYTES_SIZE } from '../../src/constants' import { asBytes, asNumber, asUint64 } from '../../src/util' -class ATestContract extends arc4.Contract { - uint64BoxRef = BoxRef() -} - const TEST_BOX_KEY = 'test_key' const BOX_NOT_CREATED_ERROR = 'Box has not been created' @@ -18,11 +14,6 @@ describe('BoxRef', () => { ctx.reset() }) - it('can be initialised without key', () => { - const contract = ctx.contract.create(ATestContract) - expect(contract.uint64BoxRef.key.toString()).toBe('uint64BoxRef') - }) - test.each(['key', Bytes('key')])('can be initialised with key %s', (key) => { ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { const box = BoxRef({ key }) diff --git a/tests/references/box.spec.ts b/tests/references/box.spec.ts index 333d280..b3cc35c 100644 --- a/tests/references/box.spec.ts +++ b/tests/references/box.spec.ts @@ -1,14 +1,10 @@ -import { arc4, BigUint, Box, Bytes, op, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { BigUint, Box, Bytes, op, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { itob } from '@algorandfoundation/algorand-typescript/op' import { afterEach, describe, expect, it, test } from 'vitest' import { asBytes, toBytes } from '../../src/util' import { BoxContract } from '../artifacts/box-contract/contract.algo' -class ATestContract extends arc4.Contract { - uint64Box = Box() -} - const BOX_NOT_CREATED_ERROR = 'Box has not been created' describe('Box', () => { @@ -18,11 +14,6 @@ describe('Box', () => { ctx.reset() }) - it('can be initialised without key', () => { - const contract = ctx.contract.create(ATestContract) - expect(contract.uint64Box.key.toString()).toBe('uint64Box') - }) - test.for(['key', Bytes('key')])('can be initialised with key %s', (key) => { ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { const box = Box({ key }) From 865e0499a33e9dfe6eb85ea575f70eb44a2f8971 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 29 Oct 2024 17:23:32 +0800 Subject: [PATCH 40/85] feat: using Uint8Array as backing store for all box values - also: - expand generic type info being captured to include type info for all levels - capture generic type info for variables initialised in a function to make test code simpler to write for boxes - update box and box map implementations and tests to work with encoders --- src/encoders.ts | 66 ++++++++ src/impl/application.ts | 2 +- src/impl/base.ts | 21 ++- src/impl/box.ts | 45 ++---- src/impl/state.ts | 32 +++- src/runtime-helpers.ts | 7 +- src/subcontexts/contract-context.ts | 10 +- src/subcontexts/ledger-context.ts | 6 +- src/test-transformer/node-factory.ts | 4 +- src/test-transformer/visitors.ts | 65 +++++++- src/util.ts | 2 + tests/artifacts/box-contract/contract.algo.ts | 8 +- tests/references/box-map.spec.ts | 145 ++++++++++++------ tests/references/box.spec.ts | 108 ++++++++++--- 14 files changed, 386 insertions(+), 135 deletions(-) create mode 100644 src/encoders.ts diff --git a/src/encoders.ts b/src/encoders.ts new file mode 100644 index 0000000..3b96eea --- /dev/null +++ b/src/encoders.ts @@ -0,0 +1,66 @@ +import { biguint, BigUint, bytes, Bytes, internal, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import { OnCompleteAction } from '@algorandfoundation/algorand-typescript/arc4' +import { AccountCls } from './impl/account' +import { ApplicationCls } from './impl/application' +import { AssetCls } from './impl/asset' + +export interface GenericTypeInfo { + name: string + wtypeName?: string + genericArgs?: GenericTypeInfo[] +} + +type fromBytes = (val: Uint8Array, typeInfo: GenericTypeInfo) => T + +const booleanFromBytes: fromBytes = (val) => { + return internal.encodingUtil.uint8ArrayToBigInt(val) > 0n +} + +const bigUintFromBytes: fromBytes = (val) => { + return BigUint(internal.encodingUtil.uint8ArrayToBigInt(val)) +} + +const bytesFromBytes: fromBytes = (val) => { + return Bytes(val) +} + +const stringFromBytes: fromBytes = (val) => { + return Bytes(val).toString() +} + +const uint64FromBytes: fromBytes = (val) => { + return Uint64(internal.encodingUtil.uint8ArrayToBigInt(val)) +} + +const onCompletionFromBytes: fromBytes = (val) => { + return Uint64(internal.encodingUtil.uint8ArrayToBigInt(val)) as OnCompleteAction +} + +const transactionTypeFromBytes: fromBytes = (val) => { + return Uint64(internal.encodingUtil.uint8ArrayToBigInt(val)) as TransactionType +} + +export const encoders = { + account: AccountCls.fromBytes, + Account: AccountCls.fromBytes, + application: ApplicationCls.fromBytes, + Application: ApplicationCls.fromBytes, + asset: AssetCls.fromBytes, + Asset: AssetCls.fromBytes, + bool: booleanFromBytes, + boolean: booleanFromBytes, + biguint: bigUintFromBytes, + bytes: bytesFromBytes, + string: stringFromBytes, + uint64: uint64FromBytes, + OnCompleteAction: onCompletionFromBytes, + TransactionType: transactionTypeFromBytes, +} + +export const getEncoder = (typeInfo: GenericTypeInfo): fromBytes => { + const encoder = encoders[typeInfo.name as keyof typeof encoders] + if (!encoder) { + throw new Error(`No encoder found for type ${typeInfo.name}`) + } + return encoder as fromBytes +} diff --git a/src/impl/application.ts b/src/impl/application.ts index 9d2db5e..013b3b3 100644 --- a/src/impl/application.ts +++ b/src/impl/application.ts @@ -13,7 +13,7 @@ export class ApplicationData { appLogs: bytes[] globalStates: BytesMap> localStates: BytesMap> - boxes: BytesMap + boxes: BytesMap } isCreating: boolean = false diff --git a/src/impl/base.ts b/src/impl/base.ts index 15f5f94..66933fa 100644 --- a/src/impl/base.ts +++ b/src/impl/base.ts @@ -1,13 +1,25 @@ -import { bytes, uint64 } from '@algorandfoundation/algorand-typescript' +import { Bytes, bytes, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import type { GenericTypeInfo } from '../encoders' export abstract class BytesBackedCls { #value: bytes + // #typeInfo: GenericTypeInfo | undefined get bytes() { return this.#value } - constructor(value: bytes) { + constructor(value: bytes, _typeInfo?: GenericTypeInfo) { this.#value = value + // this.#typeInfo = typeInfo + } + + static fromBytes( + this: { new (v: bytes, typeInfo?: GenericTypeInfo): T }, + value: Uint8Array, + typeInfo?: GenericTypeInfo, + ) { + return new this(Bytes(value), typeInfo) } } @@ -21,4 +33,9 @@ export abstract class Uint64BackedCls { constructor(value: uint64) { this.#value = value } + + static fromBytes(this: { new (v: uint64): T }, value: Uint8Array) { + const uint64Value = Uint64(encodingUtil.uint8ArrayToBigInt(value)) + return new this(uint64Value) + } } diff --git a/src/impl/box.ts b/src/impl/box.ts index af6607d..a9a6002 100644 --- a/src/impl/box.ts +++ b/src/impl/box.ts @@ -1,7 +1,7 @@ import { bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes, asBytesCls, asNumber, conactUint8Arrays, toBytes } from '../util' +import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays, toBytes } from '../util' export const Box: internal.opTypes.BoxType = { create(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): boolean { @@ -35,11 +35,7 @@ export const Box: internal.opTypes.BoxType = { throw new internal.errors.InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) - if (boxContent instanceof Uint8Array) { - return toBytes(boxContent.slice(start, start + length)) - } - const result = toBytes(boxContent).slice(start, start + length) - return result + return toBytes(boxContent.slice(start, start + length)) }, get(a: internal.primitives.StubBytesCompat): readonly [bytes, boolean] { const name = asBytes(a) @@ -52,43 +48,34 @@ export const Box: internal.opTypes.BoxType = { const app = lazyContext.activeApplication const boxContent = lazyContext.ledger.getBox(app, name) const exists = lazyContext.ledger.boxExists(app, name) - if (boxContent instanceof Uint8Array) { - return [boxContent.length, exists] - } - const bytesContent = toBytes(boxContent) - return [bytesContent.length, exists] + return [boxContent.length, exists] }, put(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubBytesCompat): void { const name = asBytes(a) const app = lazyContext.activeApplication - const newContent = asBytes(b) + const newContent = asBytesCls(b) if (lazyContext.ledger.boxExists(app, name)) { const boxContent = lazyContext.ledger.getBox(app, name) - const length = boxContent instanceof Uint8Array ? boxContent.length : toBytes(boxContent).length + const length = boxContent.length if (asNumber(length) !== asNumber(newContent.length)) { throw new internal.errors.InternalError('New content length does not match existing box length') } } - lazyContext.ledger.setBox(app, name, newContent) + lazyContext.ledger.setBox(app, name, newContent.asUint8Array()) }, replace(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat, c: internal.primitives.StubBytesCompat): void { const name = asBytes(a) const start = asNumber(b) - const newContent = asBytesCls(c).asUint8Array() + const newContent = asUint8Array(c) const app = lazyContext.activeApplication if (!lazyContext.ledger.boxExists(app, name)) { throw new internal.errors.InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) - const uint8ArrayContent = boxContent instanceof Uint8Array ? boxContent : asBytesCls(toBytes(boxContent)).asUint8Array() - if (start + newContent.length > uint8ArrayContent.length) { + if (start + newContent.length > boxContent.length) { throw new internal.errors.InternalError('Replacement content exceeds box size') } - const updatedContent = conactUint8Arrays( - uint8ArrayContent.slice(0, start), - newContent, - uint8ArrayContent.slice(start + newContent.length), - ) + 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 { @@ -99,13 +86,12 @@ export const Box: internal.opTypes.BoxType = { throw new internal.errors.InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) - const uint8ArrayContent = boxContent instanceof Uint8Array ? boxContent : asBytesCls(toBytes(boxContent)).asUint8Array() - const size = uint8ArrayContent.length + const size = boxContent.length let updatedContent if (newSize > size) { - updatedContent = conactUint8Arrays(uint8ArrayContent, new Uint8Array(Array(newSize - size).fill(0))) + updatedContent = conactUint8Arrays(boxContent, new Uint8Array(Array(newSize - size).fill(0))) } else { - updatedContent = uint8ArrayContent.slice(0, newSize) + updatedContent = boxContent.slice(0, newSize) } lazyContext.ledger.setBox(app, name, updatedContent) }, @@ -118,19 +104,18 @@ export const Box: internal.opTypes.BoxType = { const name = asBytes(a) const start = asNumber(b) const length = asNumber(c) - const newContent = asBytesCls(d).asUint8Array() + const newContent = asUint8Array(d) const app = lazyContext.activeApplication if (!lazyContext.ledger.boxExists(app, name)) { throw new internal.errors.InternalError('Box does not exist') } const boxContent = lazyContext.ledger.getBox(app, name) - const uint8ArrayContent = boxContent instanceof Uint8Array ? boxContent : asBytesCls(toBytes(boxContent)).asUint8Array() - const size = uint8ArrayContent.length + const size = boxContent.length if (start > size) { throw new internal.errors.InternalError('Start index exceeds box size') } const end = Math.min(start + length, size) - let updatedContent = conactUint8Arrays(uint8ArrayContent.slice(0, start), newContent, uint8ArrayContent.slice(end)) + let updatedContent = conactUint8Arrays(boxContent.slice(0, start), newContent, boxContent.slice(end)) // Adjust the size if necessary if (updatedContent.length > size) { updatedContent = updatedContent.slice(0, size) diff --git a/src/impl/state.ts b/src/impl/state.ts index 63d1b32..d14f7a6 100644 --- a/src/impl/state.ts +++ b/src/impl/state.ts @@ -4,6 +4,7 @@ import { BoxMap as BoxMapType, BoxRef as BoxRefType, Box as BoxType, + Bytes, bytes, GlobalStateOptions, GlobalState as GlobalStateType, @@ -16,7 +17,9 @@ import { import { AccountMap } from '../collections/custom-key-map' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes, asBytesCls, asNumber, conactUint8Arrays, toBytes } from '../util' +import { getEncoder } from '../encoders' +import { getGenericTypeInfo } from '../runtime-helpers' +import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays, toBytes } from '../util' export class GlobalStateCls { private readonly _type: string = GlobalStateCls.name @@ -126,14 +129,21 @@ export class BoxCls { this.#app = lazyContext.activeApplication } + private get fromBytes() { + const typeInfo = getGenericTypeInfo(this) + const valueType = typeInfo!.genericArgs![0] + return (val: Uint8Array) => getEncoder(valueType)(val, valueType) + } + get value(): TValue { if (!this.exists) { throw new internal.errors.InternalError('Box has not been created') } - return lazyContext.ledger.getBox(this.#app, this.key) + + return this.fromBytes(lazyContext.ledger.getBox(this.#app, this.key)) } set value(v: TValue) { - lazyContext.ledger.setBox(this.#app, this.key, v) + lazyContext.ledger.setBox(this.#app, this.key, asUint8Array(toBytes(v))) } get hasKey(): boolean { @@ -172,7 +182,8 @@ export class BoxCls { } maybe(): readonly [TValue, boolean] { - return [lazyContext.ledger.getBox(this.#app, this.key), lazyContext.ledger.boxExists(this.#app, this.key)] + const value = this.fromBytes(lazyContext.ledger.getBox(this.#app, this.key)) + return [value, lazyContext.ledger.boxExists(this.#app, this.key)] } } @@ -186,6 +197,12 @@ 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![1] + return (val: Uint8Array) => getEncoder(valueType)(val, valueType) + } + constructor(keyPrefix?: internal.primitives.StubBytesCompat) { this.#keyPrefix = keyPrefix ? asBytes(keyPrefix) : undefined this.#app = lazyContext.activeApplication @@ -215,7 +232,7 @@ export class BoxMapCls { } set(key: TKey, value: TValue): void { - lazyContext.ledger.setBox(this.#app, this.getFullKey(key), value) + lazyContext.ledger.setBox(this.#app, this.getFullKey(key), asUint8Array(toBytes(value))) } delete(key: TKey): boolean { @@ -228,7 +245,8 @@ export class BoxMapCls { maybe(key: TKey): readonly [TValue, boolean] { const fullKey = this.getFullKey(key) - return [lazyContext.ledger.getBox(this.#app, fullKey), lazyContext.ledger.boxExists(this.#app, fullKey)] + const value = this.fromBytes(lazyContext.ledger.getBox(this.#app, fullKey)) + return [value, lazyContext.ledger.boxExists(this.#app, fullKey)] } length(key: TKey): uint64 { @@ -394,7 +412,7 @@ export class BoxRefCls { } maybe(): readonly [bytes, boolean] { - return [asBytes(lazyContext.ledger.getBox(this.#app, this.key)), lazyContext.ledger.boxExists(this.#app, this.key)] + return [Bytes(lazyContext.ledger.getBox(this.#app, this.key)), lazyContext.ledger.boxExists(this.#app, this.key)] } get length(): uint64 { diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index b7f043f..36bb2f5 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -1,5 +1,6 @@ import { internal } from '@algorandfoundation/algorand-typescript' import { MAX_UINT64 } from './constants' +import type { GenericTypeInfo } from './encoders' import { DeliberateAny } from './typescript-helpers' import { nameOfType } from './util' @@ -273,12 +274,12 @@ function defaultUnaryOp(_operand: DeliberateAny, op: UnaryOps): DeliberateAny { internal.errors.internalError(`Unsupported operator ${op}`) } -const genericTypeMap = new Map() +const genericTypeMap = new Map() export function captureGenericTypeInfo(target: DeliberateAny, t: string) { - genericTypeMap.set(target, t) + genericTypeMap.set(target, JSON.parse(t)) return target } -export function getGenericTypeInfo(target: DeliberateAny): string | undefined { +export function getGenericTypeInfo(target: DeliberateAny): GenericTypeInfo | undefined { return genericTypeMap.get(target) } diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 37f42b8..4760284 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -2,6 +2,7 @@ import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, Loca import { getAbiMetadata } from '../abi-metadata' import { BytesMap } from '../collections/custom-key-map' import { lazyContext } from '../context-helpers/internal-context' +import type { GenericTypeInfo } from '../encoders' import { AccountCls } from '../impl/account' import { ApplicationCls } from '../impl/application' import { AssetCls } from '../impl/asset' @@ -17,7 +18,7 @@ import { } from '../impl/transactions' import { getGenericTypeInfo } from '../runtime-helpers' import { DeliberateAny } from '../typescript-helpers' -import { asUint64Cls, extractGenericTypeArgs } from '../util' +import { asUint64Cls } from '../util' interface IConstructor { new (...args: DeliberateAny[]): T @@ -31,10 +32,9 @@ interface States { totals: StateTotals } -const isUint64GenericType = (typeName: string | undefined) => { - if (typeName === undefined) return false - const genericTypes: string[] = extractGenericTypeArgs(typeName) - return genericTypes.some((t) => t.toLocaleLowerCase() === 'uint64') +const isUint64GenericType = (typeInfo: GenericTypeInfo | undefined) => { + if (!typeInfo?.genericArgs?.length) return false + return typeInfo.genericArgs.some((t) => t.name.toLocaleLowerCase() === 'uint64') } const extractStates = (contract: BaseContract): States => { diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index 69ebdb5..b943539 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -153,12 +153,12 @@ export class LedgerContext { } } - getBox(app: Application, key: internal.primitives.StubBytesCompat): TValue { + getBox(app: Application, key: internal.primitives.StubBytesCompat): Uint8Array { const appData = this.applicationDataMap.getOrFail(app.id) - return appData.application.boxes.get(key) as TValue + return appData.application.boxes.get(key) ?? new Uint8Array() } - setBox(app: Application, key: internal.primitives.StubBytesCompat, value: TValue): void { + setBox(app: Application, key: internal.primitives.StubBytesCompat, value: Uint8Array): void { const appData = this.applicationDataMap.getOrFail(app.id) appData.application.boxes.set(key, value) } diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 6fc7415..38dd57d 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -57,14 +57,14 @@ export const nodeFactory = { ) }, - captureGenericTypeInfo(x: ts.Expression, type: string) { + captureGenericTypeInfo(x: ts.Expression, info: string) { return factory.createCallExpression( factory.createPropertyAccessExpression( factory.createIdentifier('runtimeHelpers'), factory.createIdentifier('captureGenericTypeInfo'), ), undefined, - [x, factory.createStringLiteral(type)], + [x, factory.createStringLiteral(info)], ) }, } satisfies Record ts.Node> diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index c701cc7..f1d7b4d 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -1,5 +1,7 @@ import { anyPType, ContractClassPType, FunctionPType, PType, SourceLocation, typeRegistry, TypeResolver } from '@algorandfoundation/puya-ts' import ts from 'typescript' +import type { GenericTypeInfo } from '../encoders' +import { DeliberateAny } from '../typescript-helpers' import { TransformerConfig } from './index' import { nodeFactory } from './node-factory' import { supportedBinaryOpString, supportedPrefixUnaryOpString } from './supported-binary-op-string' @@ -49,7 +51,7 @@ export class SourceFileVisitor { private visit = (node: ts.Node): ts.Node => { if (ts.isFunctionLike(node)) { - return new FunctionLikeDecVisitor(this.context, node).result() + return new FunctionLikeDecVisitor(this.context, this.helper, node).result() } if (ts.isClassDeclaration(node)) { return new ClassVisitor(this.context, this.helper, node).result() @@ -60,7 +62,11 @@ export class SourceFileVisitor { } class FunctionOrMethodVisitor { - constructor(protected context: ts.TransformationContext) {} + 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) } @@ -86,6 +92,28 @@ class FunctionOrMethodVisitor { return nodeFactory.prefixUnaryOp(node.operand, tokenText) } } + /* + * capture generic type info in test functions; e.g. + * ``` + * it('should work', () => { + * ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + * const box = Box({key: Bytes('test-key')}) + * }) + * }) + * ``` + */ + if (this.isFunction && ts.isVariableDeclaration(node) && node.initializer && ts.isCallExpression(node.initializer)) { + const initializerNode = node.initializer + let type = this.helper.resolveType(initializerNode) + + // `voted = LocalState()` is resolved to FunctionPType with returnType LocalState + if (type instanceof FunctionPType) type = type.returnType + if (typeRegistry.isGeneric(type)) { + const info = getGenericTypeInfo(type) + const updatedInitializer = nodeFactory.captureGenericTypeInfo(initializerNode, JSON.stringify(info)) + return factory.updateVariableDeclaration(node, node.name, node.exclamationToken, node.type, updatedInitializer) + } + } return node } } @@ -93,9 +121,10 @@ class FunctionOrMethodVisitor { class FunctionLikeDecVisitor extends FunctionOrMethodVisitor { constructor( context: ts.TransformationContext, + helper: VisitorHelper, private funcNode: ts.SignatureDeclaration, ) { - super(context) + super(context, helper, true) } public result(): ts.SignatureDeclaration { @@ -105,9 +134,10 @@ class FunctionLikeDecVisitor extends FunctionOrMethodVisitor { class MethodDecVisitor extends FunctionOrMethodVisitor { constructor( context: ts.TransformationContext, + helper: VisitorHelper, private methodNode: ts.MethodDeclaration, ) { - super(context) + super(context, helper) } public result(): ts.MethodDeclaration { @@ -139,7 +169,7 @@ class ClassVisitor { } } - return new MethodDecVisitor(this.context, node).result() + return new MethodDecVisitor(this.context, this.helper, node).result() } if (ts.isCallExpression(node)) { @@ -149,10 +179,31 @@ class ClassVisitor { if (type instanceof FunctionPType) type = type.returnType if (typeRegistry.isGeneric(type)) { - const typeName = type.name - return nodeFactory.captureGenericTypeInfo(ts.visitEachChild(node, this.visit, this.context), typeName) + const info = getGenericTypeInfo(type) + return nodeFactory.captureGenericTypeInfo(ts.visitEachChild(node, this.visit, this.context), JSON.stringify(info)) } } return ts.visitEachChild(node, this.visit, this.context) } } + +const getGenericTypeInfo = (type: PType | PType['wtype']): GenericTypeInfo => { + let genericArgs = undefined + let wtypeName = undefined + if (type instanceof PType) { + genericArgs = typeRegistry.isGeneric(type) + ? type.getGenericArgs().map(getGenericTypeInfo) + : type.wtype && Object.hasOwn(type.wtype, 'types') + ? (type.wtype as DeliberateAny).types.map(getGenericTypeInfo) + : undefined + wtypeName = type.wtype?.name + } else if (type) { + genericArgs = Object.hasOwn(type, 'types') ? (type as DeliberateAny).types.map(getGenericTypeInfo) : undefined + wtypeName = type.name + } + const result: GenericTypeInfo = { name: type?.name ?? 'unknown', wtypeName: wtypeName } + if (genericArgs && genericArgs.length) { + result.genericArgs = genericArgs + } + return result +} diff --git a/src/util.ts b/src/util.ts index f56d316..a5da4ca 100644 --- a/src/util.ts +++ b/src/util.ts @@ -43,6 +43,8 @@ export const asBigUint = (val: internal.primitives.StubBigUintCompat) => asBigUi export const asBytes = (val: internal.primitives.StubBytesCompat) => asBytesCls(val).asAlgoTs() +export const asUint8Array = (val: internal.primitives.StubBytesCompat) => asBytesCls(val).asUint8Array() + //TODO: handle arc4 types, bytes backed types export const toBytes = (val: unknown): bytes => { const uint64Val = asMaybeUint64Cls(val) diff --git a/tests/artifacts/box-contract/contract.algo.ts b/tests/artifacts/box-contract/contract.algo.ts index 1bcdff8..5411aab 100644 --- a/tests/artifacts/box-contract/contract.algo.ts +++ b/tests/artifacts/box-contract/contract.algo.ts @@ -1,8 +1,14 @@ -import { arc4, assert, Box, Bytes, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, Box, bytes, Bytes, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +type X = [a: uint64, b: string, c: bytes] +type Y = { a: uint64; b: string; c: bytes } +type Z = { x: X; y: Y } export class BoxContract extends arc4.Contract { oca = Box({ key: Bytes('oca') }) txn = Box({ key: Bytes('txn') }) + a = Box({ key: Bytes('a') }) + b = Box({ key: Bytes('b') }) + c = Box({ key: Bytes('c') }) @arc4.abimethod() public storeEnums(): void { diff --git a/tests/references/box-map.spec.ts b/tests/references/box-map.spec.ts index 9f8272e..32ebbdb 100644 --- a/tests/references/box-map.spec.ts +++ b/tests/references/box-map.spec.ts @@ -1,13 +1,39 @@ -import { BigUint, BoxMap, Bytes, bytes, op, Uint64 } from '@algorandfoundation/algorand-typescript' +import { biguint, BigUint, BoxMap, Bytes, bytes, op, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, test } from 'vitest' -import { asBytes, toBytes } from '../../src/util' +import { MAX_UINT64 } from '../../src/constants' +import { DeliberateAny } from '../../src/typescript-helpers' +import { asBigUintCls, asBytes, asUint64Cls, toBytes } from '../../src/util' const BOX_NOT_CREATED_ERROR = 'Box has not been created' describe('BoxMap', () => { const ctx = new TestExecutionContext() - + const keyPrefix = Bytes('test_key_prefix') + const testUint64BoxMap = (test: (boxMap: BoxMap) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap({ keyPrefix }) + test(boxMap) + }) + } + const testBytesBoxMap = (test: (boxMap: BoxMap) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap({ keyPrefix }) + test(boxMap) + }) + } + const testStringBoxMap = (test: (boxMap: BoxMap) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap({ keyPrefix }) + test(boxMap) + }) + } + const testBigUintBoxMap = (test: (boxMap: BoxMap) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap({ keyPrefix }) + test(boxMap) + }) + } afterEach(() => { ctx.reset() }) @@ -24,42 +50,40 @@ describe('BoxMap', () => { }) // TODO: add tests for settign arc4 types as value - test.for([ - [Bytes('abc'), Uint64(100)], - ['def', Bytes('Test')], - [BigUint(123), 'Test'], - ])('key %s and value %s can be set as value', ([key, value]) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const keyPrefix = Bytes('test_key_prefix') - const box = BoxMap({ keyPrefix }) - box.set(key, value) - - const boxContent = box.get(key) + test.each([ + [Bytes('abc'), Uint64(100), testUint64BoxMap], + ['def', Bytes('Test'), testBytesBoxMap], + [BigUint(123), 'Test', testStringBoxMap], + [Uint64(456), BigUint(MAX_UINT64), testBigUintBoxMap], + ])('key %s and value %s can be set as value', (key, value, testBoxMap) => { + testBoxMap((boxMap) => { + boxMap.set(key as never, value as never) + + const boxContent = (boxMap as DeliberateAny).get(key) const fullKey = keyPrefix.concat(toBytes(key)) const [opBoxContent, opExists] = op.Box.get(fullKey) const [opLength, _] = op.Box.length(fullKey) expect(opExists).toBe(true) - expect(box.length(key)).toEqual(opLength) + expect(boxMap.length(key as never)).toEqual(opLength) expect(toBytes(boxContent)).toEqual(opBoxContent) }) }) // TODO: add tests for settign arc4 types as value - test.for([ - [Bytes('abc'), Uint64(100)], - ['def', Bytes('Test')], - [BigUint(123), 'Test'], - ])('key %s and value %s can be delete', ([key, value]) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const keyPrefix = Bytes('test_key_prefix') - const box = BoxMap({ keyPrefix }) - box.set(key, value) - - box.delete(key) - - expect(() => box.get(key)).toThrow(BOX_NOT_CREATED_ERROR) + test.each([ + [Bytes('abc'), Uint64(100), testUint64BoxMap], + ['def', Bytes('Test'), testBytesBoxMap], + [BigUint(123), 'Test', testStringBoxMap], + [Uint64(456), BigUint(MAX_UINT64), testBigUintBoxMap], + ])('key %s and value %s can be delete', (key, value, testBoxMap) => { + testBoxMap((boxMap) => { + boxMap.set(key as never, value as never) + + boxMap.delete(key as never) + + expect(() => (boxMap as DeliberateAny).get(key)).toThrow(BOX_NOT_CREATED_ERROR) const fullKey = keyPrefix.concat(toBytes(key)) const [opBoxContent, opExists] = op.Box.get(fullKey) expect(opExists).toBe(false) @@ -68,17 +92,16 @@ describe('BoxMap', () => { }) // TODO: add tests for settign arc4 types as value - test.for([ - [Bytes('abc'), Uint64(100)], - ['def', Bytes('Test')], - [BigUint(123), 'Test'], - ])('can retrieve existing key %s and value %s using maybe', ([key, value]) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const keyPrefix = Bytes('test_key_prefix') - const box = BoxMap({ keyPrefix }) - box.set(key, value) + test.each([ + [Bytes('abc'), Uint64(100), testUint64BoxMap], + ['def', Bytes('Test'), testBytesBoxMap], + [BigUint(123), 'Test', testStringBoxMap], + [Uint64(456), BigUint(MAX_UINT64), testBigUintBoxMap], + ])('can retrieve existing key %s and value %s using maybe', (key, value, testBoxMap) => { + testBoxMap((boxMap) => { + boxMap.set(key as never, value as never) - const [content, exists] = box.maybe(key) + const [content, exists] = boxMap.maybe(key as never) const fullKey = keyPrefix.concat(toBytes(key)) const [opContent, opExists] = op.Box.get(fullKey) @@ -86,25 +109,26 @@ describe('BoxMap', () => { expect(exists).toBe(true) expect(opExists).toBe(true) - expect(box.length(key)).toEqual(opLength) + expect(boxMap.length(key as never)).toEqual(opLength) expect(toBytes(content)).toEqual(opContent) }) }) - test.for([ - [Bytes('abc'), Uint64(100)], - ['def', Bytes('Test')], - [BigUint(123), 'Test'], - ])('can retrieve non-existing value using maybe', ([key, value]) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const keyPrefix = Bytes('test_key_prefix') - const box = BoxMap({ keyPrefix }) - box.set(key, value) - box.delete(key) - const [content, exists] = box.maybe(key) + // TODO: add tests for settign arc4 types as value + test.each([ + [Bytes('abc'), Uint64(100), Uint64(0), testUint64BoxMap], + ['def', Bytes('Test'), Bytes(''), testBytesBoxMap], + [BigUint(123), 'Test', '', testStringBoxMap], + [Uint64(456), BigUint(MAX_UINT64), BigUint(0), testBigUintBoxMap], + ])('can retrieve non-existing value using maybe', (key, value, expectedEmptyValue, testBoxMap) => { + testBoxMap((boxMap) => { + boxMap.set(key as never, value as never) + boxMap.delete(key as never) + + const [content, exists] = boxMap.maybe(key as never) expect(exists).toBe(false) - expect(toBytes(content)).toEqual(Bytes('')) + expect(content).toEqual(expectedEmptyValue) const fullKey = keyPrefix.concat(toBytes(key)) const [opContent, opExists] = op.Box.get(fullKey) @@ -112,4 +136,23 @@ describe('BoxMap', () => { expect(opContent).toEqual(Bytes('')) }) }) + + test.each([ + [Bytes('abc'), Uint64(100), Uint64(200), asUint64Cls(200).toBytes().asAlgoTs(), testUint64BoxMap], + ['def', Bytes('Test1'), Bytes('hello'), Bytes('hello'), testBytesBoxMap], + [BigUint(123), 'Test1', 'hello', Bytes('hello'), testStringBoxMap], + [Uint64(456), BigUint(100), BigUint(200), asBigUintCls(200).toBytes().asAlgoTs(), testBigUintBoxMap], + ])('can get typed value after using op.Box.put', (key, value, newValue, newBytesValue, testBoxMap) => { + testBoxMap((boxMap) => { + boxMap.set(key as never, value as never) + expect((boxMap as DeliberateAny).get(key)).toEqual(value) + + const fullKey = keyPrefix.concat(toBytes(key)) + op.Box.put(fullKey, newBytesValue) + const [opContent, _] = op.Box.get(fullKey) + + expect(opContent).toEqual(newBytesValue) + expect((boxMap as DeliberateAny).get(key)).toEqual(newValue) + }) + }) }) diff --git a/tests/references/box.spec.ts b/tests/references/box.spec.ts index b3cc35c..b61dfce 100644 --- a/tests/references/box.spec.ts +++ b/tests/references/box.spec.ts @@ -1,20 +1,51 @@ -import { BigUint, Box, Bytes, op, Uint64 } from '@algorandfoundation/algorand-typescript' +import { BigUint, biguint, Box, bytes, Bytes, op, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { itob } from '@algorandfoundation/algorand-typescript/op' import { afterEach, describe, expect, it, test } from 'vitest' -import { asBytes, toBytes } from '../../src/util' +import { asBigUintCls, asBytes, asUint64Cls, toBytes } from '../../src/util' import { BoxContract } from '../artifacts/box-contract/contract.algo' const BOX_NOT_CREATED_ERROR = 'Box has not been created' describe('Box', () => { const ctx = new TestExecutionContext() + const key = Bytes('test_key') + const testUint64Box = (test: (box: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + test(box) + }) + } + const testBytesBox = (test: (box: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + test(box) + }) + } + const testStringBox = (test: (box: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + test(box) + }) + } + const testBigUintBox = (test: (box: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + test(box) + }) + } + const testBooleanBox = (test: (box: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + test(box) + }) + } afterEach(() => { ctx.reset() }) - test.for(['key', Bytes('key')])('can be initialised with key %s', (key) => { + test.each(['key', Bytes('key')])('can be initialised with key %s', (key) => { ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { const box = Box({ key }) expect(box.exists).toBe(false) @@ -25,10 +56,13 @@ describe('Box', () => { }) // TODO: add tests for settign arc4 types as value - test.for([Uint64(100), Bytes('Test'), 'Test', BigUint(100)])('%s can be set as value', (value) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const key = Bytes('test_key') - const box = Box({ key }) + test.each([ + [Uint64(100), testUint64Box], + [Bytes('Test'), testBytesBox], + ['Test', testStringBox], + [BigUint(100), testBigUintBox], + ])('%s can be set as value', (value, testBox) => { + testBox((box) => { box.value = value const [content, exists] = op.Box.get(key) @@ -40,11 +74,14 @@ describe('Box', () => { }) }) - // TODO: add tests for settign arc4 types as value - test.for([Uint64(100), Bytes('Test'), 'Test', BigUint(100)])('%s value can be delete', (value) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const key = Bytes('test_key') - const box = Box({ key }) + // // TODO: add tests for settign arc4 types as value + test.each([ + [Uint64(100), testUint64Box], + [Bytes('Test'), testBytesBox], + ['Test', testStringBox], + [BigUint(100), testBigUintBox], + ])('%s value can be delete', (value, testBox) => { + testBox((box) => { box.value = value box.delete() @@ -58,11 +95,14 @@ describe('Box', () => { }) }) - // TODO: add tests for settign arc4 types as value - test.for([Uint64(100), Bytes('Test'), 'Test', BigUint(100)])('can retrieve existing value %s using maybe', (value) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const key = Bytes('test_key') - const box = Box({ key }) + // // TODO: add tests for settign arc4 types as value + test.each([ + [Uint64(100), testUint64Box], + [Bytes('Test'), testBytesBox], + ['Test', testStringBox], + [BigUint(100), testBigUintBox], + ])('can retrieve existing value %s using maybe', (value, testBox) => { + testBox((box) => { box.value = value const [content, exists] = box.maybe() @@ -74,11 +114,14 @@ describe('Box', () => { }) }) - // TODO: add tests for settign arc4 types as value - test.for([Uint64(100), Bytes('Test'), 'Test', BigUint(100)])('can retrieve non-existing value using maybe', (value) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const key = Bytes('test_key') - const box = Box({ key }) + // // TODO: add tests for settign arc4 types as value + test.each([ + [Uint64(100), testUint64Box, Uint64(0)], + [Bytes('Test'), testBytesBox, Bytes('')], + ['Test', testStringBox, ''], + [BigUint(100), testBigUintBox, BigUint(0)], + ])('can retrieve non-existing value using maybe', (value, testBox, expectedValue) => { + testBox((box) => { box.value = value box.delete() @@ -88,7 +131,7 @@ describe('Box', () => { expect(exists).toBe(false) expect(opExists).toBe(false) expect(opContent).toEqual(Bytes('')) - expect(toBytes(content)).toEqual(Bytes('')) + expect(content).toEqual(expectedValue) }) }) @@ -107,4 +150,23 @@ describe('Box', () => { expect(toBytes(ctx.ledger.getBox(app, 'txn'))).toEqual(itob(txn)) }) }) + + test.each([ + [Uint64(100), Uint64(200), asUint64Cls(200).toBytes().asAlgoTs(), testUint64Box], + [BigUint(100), BigUint(200), asBigUintCls(200).toBytes().asAlgoTs(), testBigUintBox], + [Bytes('abc'), Bytes('def'), Bytes('def'), testBytesBox], + ['abc', 'def', Bytes('def'), testStringBox], + [true, false, asUint64Cls(0).toBytes().asAlgoTs(), testBooleanBox], + ])('can get typed value after using op.Box.put', (value, newValue, newBytesValue, testBox) => { + testBox((box) => { + box.value = value + expect(box.value).toEqual(value) + + op.Box.put(key, newBytesValue) + const [opContent, _] = op.Box.get(key) + + expect(opContent).toEqual(newBytesValue) + expect(box.value).toEqual(newValue) + }) + }) }) From 2fae1ea5e333fba00b39e809f5a30f9da6ee3fcd Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 31 Oct 2024 14:51:22 +0800 Subject: [PATCH 41/85] refactor: avoid using wtype property in constructing generic type info for increased fidelity - also: - refactor: use regular expression to match encoders to the type name --- src/encoders.ts | 12 +++---- src/impl/state.ts | 6 ++-- src/subcontexts/contract-context.ts | 2 +- src/test-transformer/visitors.ts | 33 ++++++++++--------- tests/artifacts/box-contract/contract.algo.ts | 17 ++++++---- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/encoders.ts b/src/encoders.ts index 3b96eea..cf41e85 100644 --- a/src/encoders.ts +++ b/src/encoders.ts @@ -6,8 +6,7 @@ import { AssetCls } from './impl/asset' export interface GenericTypeInfo { name: string - wtypeName?: string - genericArgs?: GenericTypeInfo[] + genericArgs?: GenericTypeInfo[] | Record } type fromBytes = (val: Uint8Array, typeInfo: GenericTypeInfo) => T @@ -42,23 +41,20 @@ const transactionTypeFromBytes: fromBytes = (val) => { export const encoders = { account: AccountCls.fromBytes, - Account: AccountCls.fromBytes, application: ApplicationCls.fromBytes, - Application: ApplicationCls.fromBytes, asset: AssetCls.fromBytes, - Asset: AssetCls.fromBytes, - bool: booleanFromBytes, - boolean: booleanFromBytes, + 'bool(ean)?': booleanFromBytes, biguint: bigUintFromBytes, bytes: bytesFromBytes, string: stringFromBytes, uint64: uint64FromBytes, OnCompleteAction: onCompletionFromBytes, TransactionType: transactionTypeFromBytes, + // 'Tuple<*>': tupleFromBytes, } export const getEncoder = (typeInfo: GenericTypeInfo): fromBytes => { - const encoder = encoders[typeInfo.name as keyof typeof encoders] + const encoder = Object.entries(encoders).find(([k, _]) => new RegExp(`^${k}$`, 'i').test(typeInfo.name))?.[1] if (!encoder) { throw new Error(`No encoder found for type ${typeInfo.name}`) } diff --git a/src/impl/state.ts b/src/impl/state.ts index d14f7a6..e4ef111 100644 --- a/src/impl/state.ts +++ b/src/impl/state.ts @@ -17,7 +17,7 @@ import { import { AccountMap } from '../collections/custom-key-map' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { getEncoder } from '../encoders' +import { GenericTypeInfo, getEncoder } from '../encoders' import { getGenericTypeInfo } from '../runtime-helpers' import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays, toBytes } from '../util' @@ -131,7 +131,7 @@ export class BoxCls { private get fromBytes() { const typeInfo = getGenericTypeInfo(this) - const valueType = typeInfo!.genericArgs![0] + const valueType = (typeInfo!.genericArgs! as GenericTypeInfo[])[0] return (val: Uint8Array) => getEncoder(valueType)(val, valueType) } @@ -199,7 +199,7 @@ export class BoxMapCls { private get fromBytes() { const typeInfo = getGenericTypeInfo(this) - const valueType = typeInfo!.genericArgs![1] + const valueType = (typeInfo!.genericArgs! as GenericTypeInfo[])[1] return (val: Uint8Array) => getEncoder(valueType)(val, valueType) } diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 4760284..9a14832 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -33,7 +33,7 @@ interface States { } const isUint64GenericType = (typeInfo: GenericTypeInfo | undefined) => { - if (!typeInfo?.genericArgs?.length) return false + if (!Array.isArray(typeInfo?.genericArgs) || !typeInfo?.genericArgs?.length) return false return typeInfo.genericArgs.some((t) => t.name.toLocaleLowerCase() === 'uint64') } diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index f1d7b4d..44b7348 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -187,22 +187,25 @@ class ClassVisitor { } } -const getGenericTypeInfo = (type: PType | PType['wtype']): GenericTypeInfo => { - let genericArgs = undefined - let wtypeName = undefined - if (type instanceof PType) { - genericArgs = typeRegistry.isGeneric(type) - ? type.getGenericArgs().map(getGenericTypeInfo) - : type.wtype && Object.hasOwn(type.wtype, 'types') - ? (type.wtype as DeliberateAny).types.map(getGenericTypeInfo) - : undefined - wtypeName = type.wtype?.name - } else if (type) { - genericArgs = Object.hasOwn(type, 'types') ? (type as DeliberateAny).types.map(getGenericTypeInfo) : undefined - wtypeName = type.name +const getGenericTypeInfo = (type: PType): GenericTypeInfo => { + let genericArgs: GenericTypeInfo[] | Record | undefined = typeRegistry.isGeneric(type) + ? type.getGenericArgs().map(getGenericTypeInfo) + : undefined + + if (!genericArgs || !genericArgs.length) { + if (Object.hasOwn(type, 'items')) { + genericArgs = (type as DeliberateAny).items.map(getGenericTypeInfo) + } else if (Object.hasOwn(type, 'itemType')) { + genericArgs = [getGenericTypeInfo((type as DeliberateAny).itemType)] + } else if (Object.hasOwn(type, 'properties')) { + genericArgs = Object.fromEntries( + Object.entries((type as DeliberateAny).properties).map(([key, value]) => [key, getGenericTypeInfo(value as PType)]), + ) + } } - const result: GenericTypeInfo = { name: type?.name ?? 'unknown', wtypeName: wtypeName } - if (genericArgs && genericArgs.length) { + + const result: GenericTypeInfo = { name: type?.name ?? 'unknown' } + if (genericArgs && (genericArgs.length || Object.keys(genericArgs).length)) { result.genericArgs = genericArgs } return result diff --git a/tests/artifacts/box-contract/contract.algo.ts b/tests/artifacts/box-contract/contract.algo.ts index 5411aab..f14304d 100644 --- a/tests/artifacts/box-contract/contract.algo.ts +++ b/tests/artifacts/box-contract/contract.algo.ts @@ -1,14 +1,17 @@ -import { arc4, assert, Box, bytes, Bytes, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, Box, Bytes, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' + +// type X = [a: uint64, b: string, c: bytes] +// type Y = { a: uint64; b: string; c: bytes } +// type Z = { x: X; y: Y } -type X = [a: uint64, b: string, c: bytes] -type Y = { a: uint64; b: string; c: bytes } -type Z = { x: X; y: Y } export class BoxContract extends arc4.Contract { oca = Box({ key: Bytes('oca') }) txn = Box({ key: Bytes('txn') }) - a = Box({ key: Bytes('a') }) - b = Box({ key: Bytes('b') }) - c = Box({ key: Bytes('c') }) + + // a = Box({ key: Bytes('a') }) + // b = Box({ key: Bytes('b') }) + // c = Box({ key: Bytes('c') }) + // d = Box({ key: Bytes('d') }) @arc4.abimethod() public storeEnums(): void { From 17ce036ae95e7a0b447e4b670d06a95610810dfa Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 31 Oct 2024 15:32:45 +0800 Subject: [PATCH 42/85] chore: update algots package version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2c41b93..6cd6f0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.13", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.15", "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", "algosdk": "^2.9.0", "elliptic": "^6.5.7", @@ -105,9 +105,9 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.13", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.13.tgz", - "integrity": "sha512-rm+rPwO1j3rY5i95vvu7CMsv0JkguP9fsJIe/AB9eD6pnWaR8do6cCl/LbR6ow+5/3B8nLTt00l+rbvq5ibLwg==", + "version": "0.0.1-alpha.15", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.15.tgz", + "integrity": "sha512-iIKBVO6dNz1F2acD6ymhbe4gNIDywZAR7vKxPq5BV7aZoS/mtJkur9oTniyDTAfBZl5JqY3qNDuJUlGZa9K/9w==", "peerDependencies": { "tslib": "^2.6.2" } diff --git a/package.json b/package.json index c9d8b3f..3da2f34 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ }, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.13", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.15", "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", "algosdk": "^2.9.0", "elliptic": "^6.5.7", From c8abc46f5e9b71851bca673989eaf01a4bbbbb72 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 31 Oct 2024 15:38:56 +0800 Subject: [PATCH 43/85] refactor: according to review feedback - use weak map to store generic type info - rename GenericTypeInfo interface to TypeInfo - stop explicitly filling Uint8Array with 0 as it is the default behaviour --- src/encoders.ts | 8 ++++---- src/impl/base.ts | 10 +++------- src/impl/box.ts | 6 +++--- src/impl/pure.ts | 2 +- src/impl/state.ts | 12 ++++++------ src/runtime-helpers.ts | 6 +++--- src/subcontexts/contract-context.ts | 4 ++-- src/test-transformer/visitors.ts | 8 ++++---- tests/primitives/bytes.spec.ts | 2 +- tests/references/asset.spec.ts | 2 +- tests/references/box-ref.spec.ts | 12 ++++++------ tests/util.ts | 2 +- 12 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/encoders.ts b/src/encoders.ts index cf41e85..cfcf841 100644 --- a/src/encoders.ts +++ b/src/encoders.ts @@ -4,12 +4,12 @@ import { AccountCls } from './impl/account' import { ApplicationCls } from './impl/application' import { AssetCls } from './impl/asset' -export interface GenericTypeInfo { +export interface TypeInfo { name: string - genericArgs?: GenericTypeInfo[] | Record + genericArgs?: TypeInfo[] | Record } -type fromBytes = (val: Uint8Array, typeInfo: GenericTypeInfo) => T +type fromBytes = (val: Uint8Array, typeInfo: TypeInfo) => T const booleanFromBytes: fromBytes = (val) => { return internal.encodingUtil.uint8ArrayToBigInt(val) > 0n @@ -53,7 +53,7 @@ export const encoders = { // 'Tuple<*>': tupleFromBytes, } -export const getEncoder = (typeInfo: GenericTypeInfo): fromBytes => { +export const getEncoder = (typeInfo: TypeInfo): fromBytes => { const encoder = Object.entries(encoders).find(([k, _]) => new RegExp(`^${k}$`, 'i').test(typeInfo.name))?.[1] if (!encoder) { throw new Error(`No encoder found for type ${typeInfo.name}`) diff --git a/src/impl/base.ts b/src/impl/base.ts index 66933fa..0bf079f 100644 --- a/src/impl/base.ts +++ b/src/impl/base.ts @@ -1,6 +1,6 @@ import { Bytes, bytes, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { encodingUtil } from '@algorandfoundation/puya-ts' -import type { GenericTypeInfo } from '../encoders' +import type { TypeInfo } from '../encoders' export abstract class BytesBackedCls { #value: bytes @@ -9,16 +9,12 @@ export abstract class BytesBackedCls { get bytes() { return this.#value } - constructor(value: bytes, _typeInfo?: GenericTypeInfo) { + constructor(value: bytes, _typeInfo?: TypeInfo) { this.#value = value // this.#typeInfo = typeInfo } - static fromBytes( - this: { new (v: bytes, typeInfo?: GenericTypeInfo): T }, - value: Uint8Array, - typeInfo?: GenericTypeInfo, - ) { + static fromBytes(this: { new (v: bytes, typeInfo?: TypeInfo): T }, value: Uint8Array, typeInfo?: TypeInfo) { return new this(Bytes(value), typeInfo) } } diff --git a/src/impl/box.ts b/src/impl/box.ts index a9a6002..c1bdf84 100644 --- a/src/impl/box.ts +++ b/src/impl/box.ts @@ -14,7 +14,7 @@ export const Box: internal.opTypes.BoxType = { if (lazyContext.ledger.boxExists(app, name)) { return false } - lazyContext.ledger.setBox(app, name, new Uint8Array(Array(size).fill(0))) + lazyContext.ledger.setBox(app, name, new Uint8Array(size)) return true }, delete(a: internal.primitives.StubBytesCompat): boolean { @@ -89,7 +89,7 @@ export const Box: internal.opTypes.BoxType = { const size = boxContent.length let updatedContent if (newSize > size) { - updatedContent = conactUint8Arrays(boxContent, new Uint8Array(Array(newSize - size).fill(0))) + updatedContent = conactUint8Arrays(boxContent, new Uint8Array(newSize - size)) } else { updatedContent = boxContent.slice(0, newSize) } @@ -120,7 +120,7 @@ export const Box: internal.opTypes.BoxType = { if (updatedContent.length > size) { updatedContent = updatedContent.slice(0, size) } else if (updatedContent.length < size) { - updatedContent = conactUint8Arrays(updatedContent, new Uint8Array(Array(size - asNumber(updatedContent.length)).fill(0))) + updatedContent = conactUint8Arrays(updatedContent, new Uint8Array(size - asNumber(updatedContent.length))) } lazyContext.ledger.setBox(app, name, updatedContent) }, diff --git a/src/impl/pure.ts b/src/impl/pure.ts index 1dd7d7f..725e24c 100644 --- a/src/impl/pure.ts +++ b/src/impl/pure.ts @@ -52,7 +52,7 @@ export const bzero = (a: internal.primitives.StubUint64Compat): bytes => { if (size > MAX_BYTES_SIZE) { internal.errors.avmError('bzero attempted to create a too large string') } - return Bytes(new Uint8Array(Array(Number(size)).fill(0x00))) + return Bytes(new Uint8Array(Number(size))) } export const concat = (a: internal.primitives.StubBytesCompat, b: internal.primitives.StubBytesCompat): bytes => { diff --git a/src/impl/state.ts b/src/impl/state.ts index e4ef111..2382644 100644 --- a/src/impl/state.ts +++ b/src/impl/state.ts @@ -17,7 +17,7 @@ import { import { AccountMap } from '../collections/custom-key-map' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { GenericTypeInfo, getEncoder } from '../encoders' +import { getEncoder, TypeInfo } from '../encoders' import { getGenericTypeInfo } from '../runtime-helpers' import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays, toBytes } from '../util' @@ -131,7 +131,7 @@ export class BoxCls { private get fromBytes() { const typeInfo = getGenericTypeInfo(this) - const valueType = (typeInfo!.genericArgs! as GenericTypeInfo[])[0] + const valueType = (typeInfo!.genericArgs! as TypeInfo[])[0] return (val: Uint8Array) => getEncoder(valueType)(val, valueType) } @@ -199,7 +199,7 @@ export class BoxMapCls { private get fromBytes() { const typeInfo = getGenericTypeInfo(this) - const valueType = (typeInfo!.genericArgs! as GenericTypeInfo[])[1] + const valueType = (typeInfo!.genericArgs! as TypeInfo[])[1] return (val: Uint8Array) => getEncoder(valueType)(val, valueType) } @@ -320,7 +320,7 @@ export class BoxRefCls { if (this.exists) { return false } - this.backingValue = new Uint8Array(Array(size).fill(0)) + this.backingValue = new Uint8Array(size) return true } @@ -354,7 +354,7 @@ export class BoxRefCls { if (updatedContent.length > content.length) { updatedContent = updatedContent.slice(0, content.length) } else if (updatedContent.length < content.length) { - updatedContent = conactUint8Arrays(updatedContent, new Uint8Array(Array(content.length - updatedContent.length).fill(0))) + updatedContent = conactUint8Arrays(updatedContent, new Uint8Array(content.length - updatedContent.length)) } this.backingValue = updatedContent } @@ -404,7 +404,7 @@ export class BoxRefCls { } let updatedContent if (newSizeNumber > content.length) { - updatedContent = conactUint8Arrays(content, new Uint8Array(Array(newSizeNumber - content.length).fill(0))) + updatedContent = conactUint8Arrays(content, new Uint8Array(newSizeNumber - content.length)) } else { updatedContent = content.slice(0, newSize) } diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 36bb2f5..271d844 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -1,6 +1,6 @@ import { internal } from '@algorandfoundation/algorand-typescript' import { MAX_UINT64 } from './constants' -import type { GenericTypeInfo } from './encoders' +import type { TypeInfo } from './encoders' import { DeliberateAny } from './typescript-helpers' import { nameOfType } from './util' @@ -274,12 +274,12 @@ function defaultUnaryOp(_operand: DeliberateAny, op: UnaryOps): DeliberateAny { internal.errors.internalError(`Unsupported operator ${op}`) } -const genericTypeMap = new Map() +const genericTypeMap = new WeakMap() export function captureGenericTypeInfo(target: DeliberateAny, t: string) { genericTypeMap.set(target, JSON.parse(t)) return target } -export function getGenericTypeInfo(target: DeliberateAny): GenericTypeInfo | undefined { +export function getGenericTypeInfo(target: DeliberateAny): TypeInfo | undefined { return genericTypeMap.get(target) } diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 9a14832..9d4e720 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -2,7 +2,7 @@ import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, Loca import { getAbiMetadata } from '../abi-metadata' import { BytesMap } from '../collections/custom-key-map' import { lazyContext } from '../context-helpers/internal-context' -import type { GenericTypeInfo } from '../encoders' +import type { TypeInfo } from '../encoders' import { AccountCls } from '../impl/account' import { ApplicationCls } from '../impl/application' import { AssetCls } from '../impl/asset' @@ -32,7 +32,7 @@ interface States { totals: StateTotals } -const isUint64GenericType = (typeInfo: GenericTypeInfo | undefined) => { +const isUint64GenericType = (typeInfo: TypeInfo | undefined) => { if (!Array.isArray(typeInfo?.genericArgs) || !typeInfo?.genericArgs?.length) return false return typeInfo.genericArgs.some((t) => t.name.toLocaleLowerCase() === 'uint64') } diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index 44b7348..c8f2601 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -1,6 +1,6 @@ import { anyPType, ContractClassPType, FunctionPType, PType, SourceLocation, typeRegistry, TypeResolver } from '@algorandfoundation/puya-ts' import ts from 'typescript' -import type { GenericTypeInfo } from '../encoders' +import type { TypeInfo } from '../encoders' import { DeliberateAny } from '../typescript-helpers' import { TransformerConfig } from './index' import { nodeFactory } from './node-factory' @@ -187,8 +187,8 @@ class ClassVisitor { } } -const getGenericTypeInfo = (type: PType): GenericTypeInfo => { - let genericArgs: GenericTypeInfo[] | Record | undefined = typeRegistry.isGeneric(type) +const getGenericTypeInfo = (type: PType): TypeInfo => { + let genericArgs: TypeInfo[] | Record | undefined = typeRegistry.isGeneric(type) ? type.getGenericArgs().map(getGenericTypeInfo) : undefined @@ -204,7 +204,7 @@ const getGenericTypeInfo = (type: PType): GenericTypeInfo => { } } - const result: GenericTypeInfo = { name: type?.name ?? 'unknown' } + const result: TypeInfo = { name: type?.name ?? 'unknown' } if (genericArgs && (genericArgs.length || Object.keys(genericArgs).length)) { result.genericArgs = genericArgs } diff --git a/tests/primitives/bytes.spec.ts b/tests/primitives/bytes.spec.ts index 74321d5..a76d013 100644 --- a/tests/primitives/bytes.spec.ts +++ b/tests/primitives/bytes.spec.ts @@ -170,7 +170,7 @@ describe('Bytes', async () => { describe.each([MAX_BYTES_SIZE + 1, MAX_BYTES_SIZE * 2])('value overflows', (size) => { it(`${size} bytes`, () => { - const a = new Uint8Array(size).fill(0) + const a = new Uint8Array(size) expect(() => Bytes(a)).toThrow(/Bytes length \d+ exceeds maximum length/) }) }) diff --git a/tests/references/asset.spec.ts b/tests/references/asset.spec.ts index d01ac70..cf534f3 100644 --- a/tests/references/asset.spec.ts +++ b/tests/references/asset.spec.ts @@ -56,7 +56,7 @@ describe('Asset', () => { unitName: asBytes('TEST'), name: asBytes('Test Asset'), url: asBytes('https://test.com'), - metadataHash: Bytes(new Uint8Array(Array(32).fill(0x00))), + metadataHash: Bytes(new Uint8Array(32)), manager: Account(), freeze: Account(), clawback: Account(), diff --git a/tests/references/box-ref.spec.ts b/tests/references/box-ref.spec.ts index 4ee7bcf..cdd2b7d 100644 --- a/tests/references/box-ref.spec.ts +++ b/tests/references/box-ref.spec.ts @@ -31,7 +31,7 @@ describe('BoxRef', () => { expect(box.length).toBe(size) - assertBoxValue(box, new Uint8Array(Array(size).fill(0))) + assertBoxValue(box, new Uint8Array(size)) }) }) @@ -196,7 +196,7 @@ describe('BoxRef', () => { box.put(value) - const content = box.get({ default: Bytes(new Uint8Array(Array(size).fill(0x00))) }) + const content = box.get({ default: Bytes(new Uint8Array(size)) }) expect(content).toEqual(value) const [opContent, opExists] = op.Box.get(box.key) @@ -215,7 +215,7 @@ describe('BoxRef', () => { expect(box.exists).toBe(true) expect(box.length).toBe(10) - const content = box.get({ default: Bytes(new Uint8Array(Array(10).fill(0x00))) }) + const content = box.get({ default: Bytes(new Uint8Array(10)) }) expect(content).toEqual(Bytes(boxValue)) }) }) @@ -224,7 +224,7 @@ describe('BoxRef', () => { ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { const box = BoxRef({ key: TEST_BOX_KEY }) - const defaultValue = Bytes(new Uint8Array(Array(10).fill(0x00))) + const defaultValue = Bytes(new Uint8Array(10)) const content = box.get({ default: defaultValue }) expect(content).toEqual(defaultValue) }) @@ -252,7 +252,7 @@ describe('BoxRef', () => { const replacement = new Uint8Array(Array(2).fill(0x11)) box.splice(1, 1, Bytes(replacement)) - const content = box.get({ default: Bytes(new Uint8Array(Array(size).fill(0x00))) }) + const content = box.get({ default: Bytes(new Uint8Array(size)) }) const opBoxKey = asBytes('another_key') op.Box.create(opBoxKey, size) @@ -280,7 +280,7 @@ describe('BoxRef', () => { const replacement = new Uint8Array(Array(2).fill(0x11)) box.splice(1, 5, Bytes(replacement)) - const content = box.get({ default: Bytes(new Uint8Array(Array(size).fill(0x00))) }) + const content = box.get({ default: Bytes(new Uint8Array(size)) }) const opBoxKey = asBytes('another_key') op.Box.create(opBoxKey, size) diff --git a/tests/util.ts b/tests/util.ts index 856ec0c..bffce72 100644 --- a/tests/util.ts +++ b/tests/util.ts @@ -3,7 +3,7 @@ import { ABIValue } from 'algosdk' import { createHash } from 'crypto' export const padUint8Array = (arr: Uint8Array, padSize: number): Uint8Array => { - const paddedUint8Array = new Uint8Array(arr.length + padSize).fill(0) + const paddedUint8Array = new Uint8Array(arr.length + padSize) arr.forEach((v, i) => (paddedUint8Array[padSize + i] = v)) return paddedUint8Array } From 0a4df27b2ad66206b012f0928b8ba1e0b6c3ba19 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 1 Nov 2024 18:05:03 +0800 Subject: [PATCH 44/85] chore: update puya-ts package version --- package-lock.json | 4510 +++++++++++++++++++----------- package.json | 2 +- src/test-transformer/visitors.ts | 2 +- 3 files changed, 2889 insertions(+), 1625 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6cd6f0a..fd89c92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.15", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.24", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", @@ -57,43 +57,11 @@ "tslib": "^2.6.2" } }, - "../algo-ts/dist": { - "name": "@algorandfoundation/algorand-typescript", - "version": "1.0.0", - "extraneous": true, - "peerDependencies": { - "tslib": "^2.6.2" - } - }, - "../puya-ts/packages/algo-ts/dist": { - "name": "@algorandfoundation/algorand-typescript", - "version": "0.0.1-alpha.1", - "extraneous": true, - "peerDependencies": { - "tslib": "^2.6.2" - } - }, - "dist": { - "name": "@algorandfoundation/algorand-typescript-testing", - "version": "1.0.0", - "extraneous": true, - "dependencies": { - "@algorandfoundation/algokit-utils": "^6.2.1", - "algosdk": "^2.9.0", - "elliptic": "^6.5.7", - "js-sha256": "^0.11.0", - "js-sha3": "^0.9.3", - "js-sha512": "^0.9.0", - "tweetnacl": "^1.0.3" - }, - "peerDependencies": { - "tslib": "^2.6.2" - } - }, "node_modules/@algorandfoundation/algokit-utils": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-utils/-/algokit-utils-6.2.1.tgz", "integrity": "sha512-oJbqT91KJp34OasYID2guWHysCLdgZ/4GVb06sdgXxORWKKMhZa/Uj12UiACo4VzZJBOUZEJCh/QrSuHmu/m2g==", + "license": "MIT", "dependencies": { "buffer": "^6.0.3" }, @@ -113,9 +81,9 @@ } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0-alpha.14", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.14.tgz", - "integrity": "sha512-OVfc6Jh6YDG6W61YMB3O02pNSwJSKRO9P2kAmaAWImQgp1yCEZYu2N2VxJbeml09J8DJ62Vd1GkQ4P7gYD3pvg==", + "version": "1.0.0-alpha.24", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.24.tgz", + "integrity": "sha512-5nSf2eULkenlGhPWXMgTXZ+F95d81Pck1809F1ndCCBKUd3M+0RopC1IBFpWJcIJZCxsK9LTPJySLxoc+2bmIQ==", "bundleDependencies": [ "typescript" ], @@ -136,18 +104,6 @@ "puyats": "bin/run-cli.mjs" } }, - "node_modules/@algorandfoundation/puya-ts/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/@algorandfoundation/puya-ts/node_modules/typescript": { "version": "5.6.3", "inBundle": true, @@ -165,6 +121,7 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -174,12 +131,14 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -187,114 +146,34 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/types": "^7.26.0" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -303,14 +182,14 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -320,7 +199,8 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@colors/colors": { "version": "1.5.0", @@ -355,50 +235,6 @@ "node": ">=v18" } }, - "node_modules/@commitlint/cli/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@commitlint/cli/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@commitlint/cli/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/@commitlint/config-conventional": { "version": "19.5.0", "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.5.0.tgz", @@ -440,30 +276,6 @@ "node": ">=v18" } }, - "node_modules/@commitlint/config-validator/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@commitlint/config-validator/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, "node_modules/@commitlint/ensure": { "version": "19.5.0", "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.5.0.tgz", @@ -506,19 +318,6 @@ "node": ">=v18" } }, - "node_modules/@commitlint/format/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/@commitlint/is-ignored": { "version": "19.5.0", "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.5.0.tgz", @@ -571,19 +370,6 @@ "node": ">=v18" } }, - "node_modules/@commitlint/load/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/@commitlint/message": { "version": "19.5.0", "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.5.0.tgz", @@ -644,16 +430,6 @@ "node": ">=v18" } }, - "node_modules/@commitlint/resolve-extends/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@commitlint/rules": { "version": "19.5.0", "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.5.0.tgz", @@ -693,137 +469,35 @@ "node": ">=v18" } }, - "node_modules/@commitlint/top-level/node_modules/find-up": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", - "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "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==", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^7.2.0", - "path-exists": "^5.0.0", - "unicorn-magic": "^0.1.0" + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=v18" } }, - "node_modules/@commitlint/top-level/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "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==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/top-level/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/top-level/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/top-level/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/@commitlint/top-level/node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/conventional-commits-parser": "^5.0.0", - "chalk": "^5.3.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/types/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "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==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { @@ -1218,24 +892,28 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "license": "MIT", "engines": { @@ -1257,30 +935,6 @@ "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/core": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", @@ -1315,29 +969,29 @@ "url": "https://opencollective.com/eslint" } }, - "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==", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "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==", + "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", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } + "license": "MIT" }, "node_modules/@eslint/js": { "version": "9.12.0", @@ -1360,9 +1014,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", + "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1373,9 +1027,9 @@ } }, "node_modules/@humanfs/core": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", - "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1383,13 +1037,13 @@ } }, "node_modules/@humanfs/node": { - "version": "0.16.5", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", - "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanfs/core": "^0.19.0", + "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" }, "engines": { @@ -1401,6 +1055,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -1440,85 +1095,6 @@ "node": ">=12" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -1534,6 +1110,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1548,6 +1125,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -1557,6 +1135,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -1573,6 +1152,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1589,7 +1169,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@makerx/prettier-config/-/prettier-config-2.0.1.tgz", "integrity": "sha512-fI2TT312JPVrgNFASiZG8b7N4RjazYvxEd7Yq05jwTdZyTiT9eRGjKHSRc+MA9uPBeOVLWNI7PKYTCqyXTw7uA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@makerx/ts-toolkit": { "version": "4.0.0-beta.21", @@ -1611,33 +1192,89 @@ "node": ">=20.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@makerx/ts-toolkit/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": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@makerx/ts-toolkit/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, - "engines": { - "node": ">= 8" - } + "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/@makerx/ts-toolkit/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/@makerx/ts-toolkit/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/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1746,9 +1383,9 @@ } }, "node_modules/@octokit/plugin-throttling": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.3.1.tgz", - "integrity": "sha512-Qd91H4liUBhwLB2h6jZ99bsxoQdhgPk6TdwnClPyTBSDAdviGPceViEgUwj+pcQDmB/rfAXAXK7MTochpHM3yQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.3.2.tgz", + "integrity": "sha512-FqpvcTpIWFpMMwIeSoypoJXysSAQ3R+ALJhXXSG1HTP3YZOIeLmcNcimKaXxTcws+Sh6yoRl13SJ5r8sXc1Fhw==", "dev": true, "license": "MIT", "dependencies": { @@ -1792,9 +1429,9 @@ } }, "node_modules/@octokit/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.0.tgz", - "integrity": "sha512-CrooV/vKCXqwLa+osmHLIMUb87brpgUqlqkPGc6iE2wCkUvTrHiXFMhAKoDDaAAYJrtKtrFTgSQTg5nObBEaew==", + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", "dev": true, "license": "MIT", "dependencies": { @@ -1817,6 +1454,7 @@ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" }, @@ -1914,6 +1552,7 @@ "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.1.0" }, @@ -1955,9 +1594,9 @@ } }, "node_modules/@rollup/plugin-typescript": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.0.tgz", - "integrity": "sha512-Kzs8KGJofe7cfTRODsnG1jNGxSvU8gVoNNd7Z/QaY25AYwe2LSSUpx/kPxqF38NYkpR8de3m51r9uwJpDlz6dg==", + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.1.tgz", + "integrity": "sha512-t7O653DpfB5MbFrqPe/VcKFFkvRuFNp9qId3xq4Eth5xlyymzxNpye2z8Hrl0RIMuXTSr5GGcFpkdlMeacUiFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1982,14 +1621,15 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", + "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" + "picomatch": "^4.0.2" }, "engines": { "node": ">=14.0.0" @@ -2003,23 +1643,10 @@ } } }, - "node_modules/@rollup/pluginutils/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/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz", + "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==", "cpu": [ "arm" ], @@ -2031,9 +1658,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz", + "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==", "cpu": [ "arm64" ], @@ -2045,9 +1672,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz", + "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==", "cpu": [ "arm64" ], @@ -2059,9 +1686,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz", + "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==", "cpu": [ "x64" ], @@ -2072,10 +1699,38 @@ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz", + "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz", + "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz", + "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==", "cpu": [ "arm" ], @@ -2087,9 +1742,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz", + "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==", "cpu": [ "arm" ], @@ -2101,9 +1756,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz", + "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==", "cpu": [ "arm64" ], @@ -2115,9 +1770,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz", + "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==", "cpu": [ "arm64" ], @@ -2129,9 +1784,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz", + "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==", "cpu": [ "ppc64" ], @@ -2143,9 +1798,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz", + "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==", "cpu": [ "riscv64" ], @@ -2157,9 +1812,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz", + "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==", "cpu": [ "s390x" ], @@ -2171,9 +1826,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz", + "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==", "cpu": [ "x64" ], @@ -2185,9 +1840,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz", + "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==", "cpu": [ "x64" ], @@ -2199,9 +1854,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz", + "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==", "cpu": [ "arm64" ], @@ -2213,9 +1868,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz", + "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==", "cpu": [ "ia32" ], @@ -2227,9 +1882,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz", + "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==", "cpu": [ "x64" ], @@ -2381,6 +2036,21 @@ "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", @@ -2564,13 +2234,15 @@ "version": "20.1.4", "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz", "integrity": "sha512-sqgsT69YFeLWf5NtJ4Xq/xAF8p4ZQHlmGW74Nu2tD4+g5fAsposc4ZfaaPixVu4y01BEiDCWLRDCvDM5JOsRxg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/bn.js": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", - "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz", + "integrity": "sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2590,6 +2262,7 @@ "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.18.tgz", "integrity": "sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw==", "dev": true, + "license": "MIT", "dependencies": { "@types/bn.js": "*" } @@ -2629,7 +2302,8 @@ "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/semver": { "version": "7.5.8", @@ -2787,6 +2461,32 @@ } } }, + "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" + } + }, + "node_modules/@typescript-eslint/typescript-estree/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-eslint/utils": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.1.tgz", @@ -2916,9 +2616,9 @@ } }, "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": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.4.tgz", + "integrity": "sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==", "dev": true, "license": "MIT", "dependencies": { @@ -2957,6 +2657,19 @@ "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "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", @@ -2985,6 +2698,19 @@ "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==", + "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", @@ -2993,9 +2719,9 @@ "license": "BSD-2-Clause" }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", "bin": { @@ -3046,16 +2772,16 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -3094,17 +2820,20 @@ "node_modules/algosdk/node_modules/js-sha256": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==", + "license": "MIT" }, "node_modules/algosdk/node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "license": "MIT" }, "node_modules/algosdk/node_modules/js-sha512": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", - "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==", + "license": "MIT" }, "node_modules/ansi-escapes": { "version": "7.0.0", @@ -3123,25 +2852,28 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "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==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=4" } }, "node_modules/any-promise": { @@ -3155,7 +2887,8 @@ "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 + "dev": true, + "license": "Python-2.0" }, "node_modules/argv-formatter": { "version": "1.0.0", @@ -3169,6 +2902,7 @@ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -3192,6 +2926,7 @@ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -3224,6 +2959,7 @@ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3243,6 +2979,7 @@ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -3256,7 +2993,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", @@ -3275,7 +3013,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/before-after-hook": { "version": "3.0.2", @@ -3309,6 +3048,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12" } @@ -3317,6 +3057,7 @@ "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", "engines": { "node": "*" } @@ -3324,7 +3065,8 @@ "node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "license": "MIT" }, "node_modules/bottleneck": { "version": "2.19.5", @@ -3334,11 +3076,14 @@ "license": "MIT" }, "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==", + "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" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/braces": { @@ -3357,7 +3102,8 @@ "node_modules/brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "license": "MIT" }, "node_modules/buffer": { "version": "6.0.3", @@ -3377,6 +3123,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -3397,6 +3144,7 @@ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -3416,14 +3164,15 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/chai": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", - "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", "dev": true, "license": "MIT", "dependencies": { @@ -3438,16 +3187,12 @@ } }, "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, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", "engines": { - "node": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" @@ -3495,99 +3240,405 @@ "node": ">=8" } }, - "node_modules/clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dev": true, + "license": "ISC", + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-highlight/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-highlight/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/cli-highlight/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/cli-highlight/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cli-highlight/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/cli-highlight/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/cli-highlight/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-highlight/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-highlight/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-highlight/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/cli-highlight/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cli-highlight/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/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/cliui/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/cliui/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/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { - "escape-string-regexp": "5.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/clean-stack/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-highlight": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", - "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", - "dev": true, - "license": "ISC", "dependencies": { - "chalk": "^4.0.0", - "highlight.js": "^10.7.1", - "mz": "^2.4.0", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.0", - "yargs": "^16.0.0" - }, - "bin": { - "highlight": "bin/highlight" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=8.0.0", - "npm": ">=5.0.0" + "node": ">=8" } }, - "node_modules/cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { - "string-width": "^4.2.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": "10.* || >= 12.*" + "node": ">=10" }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "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==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "color-name": "1.1.3" } }, "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==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" }, "node_modules/commander": { "version": "12.1.0", @@ -3602,7 +3653,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/compare-func": { "version": "2.0.0", @@ -3626,7 +3678,8 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/config-chain": { "version": "1.1.13", @@ -3752,6 +3805,7 @@ "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", "dev": true, + "license": "MIT", "dependencies": { "glob": "^7.0.5", "minimatch": "^3.0.3", @@ -3766,22 +3820,78 @@ "copyup": "copyfiles" } }, - "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==", + "node_modules/copyfiles/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/copyfiles/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": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/copyfiles/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/copyfiles/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/copyfiles/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/copyfiles/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, "node_modules/copyfiles/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", @@ -3797,29 +3907,94 @@ "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==", + "node_modules/copyfiles/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": "*" + "node": ">=8" + } + }, + "node_modules/copyfiles/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/copyfiles/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/copyfiles/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/copyfiles/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" } }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cosmiconfig": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, + "license": "MIT", "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -3842,13 +4017,13 @@ } }, "node_modules/cosmiconfig-typescript-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", - "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.1.0.tgz", + "integrity": "sha512-7PtBB+6FdsOvZyJtlF3hEPpACq7RQX6BVGsgC7/lfVXnKMvNCu/XY3ykreqG5w/rBNdu2z8LCIKoF3kpHHdHlA==", "dev": true, "license": "MIT", "dependencies": { - "jiti": "^1.19.1" + "jiti": "^1.21.6" }, "engines": { "node": ">=v16" @@ -3863,6 +4038,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3919,6 +4095,7 @@ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -3936,6 +4113,7 @@ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -3953,6 +4131,7 @@ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -3966,10 +4145,11 @@ } }, "node_modules/dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", - "dev": true + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "dev": true, + "license": "MIT" }, "node_modules/debug": { "version": "4.3.7", @@ -4013,13 +4193,15 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4029,6 +4211,7 @@ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -4046,6 +4229,7 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -4064,9 +4248,19 @@ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4137,6 +4331,7 @@ "version": "6.6.0", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.0.tgz", "integrity": "sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==", + "license": "MIT", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -4148,9 +4343,10 @@ } }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" }, "node_modules/emojilib": { "version": "2.4.0", @@ -4280,6 +4476,7 @@ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4302,6 +4499,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } @@ -4311,6 +4509,7 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -4371,6 +4570,7 @@ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -4383,6 +4583,7 @@ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -4392,6 +4593,7 @@ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -4404,6 +4606,7 @@ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -4418,6 +4621,7 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -4471,10 +4675,11 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4484,6 +4689,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4557,6 +4763,7 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, + "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -4569,6 +4776,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", "dev": true, + "license": "MIT", "dependencies": { "prettier-linter-helpers": "^1.0.0", "synckit": "^0.9.1" @@ -4595,9 +4803,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", - "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4616,6 +4824,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4623,20 +4832,80 @@ "url": "https://opencollective.com/eslint" } }, - "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==", + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/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/eslint/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/eslint/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/eslint/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/eslint/node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "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": { @@ -4646,28 +4915,111 @@ "url": "https://opencollective.com/eslint" } }, - "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==", + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/espree": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", - "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.12.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.1.0" + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4677,9 +5029,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "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": { @@ -4690,10 +5042,11 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -4719,6 +5072,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -4727,7 +5081,8 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", @@ -4740,9 +5095,9 @@ } }, "node_modules/execa": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.4.0.tgz", - "integrity": "sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==", + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.1.tgz", + "integrity": "sha512-QY5PPtSonnGwhhHDNI7+3RvY285c7iuJFFB+lU+oEzMY/gEGJ808owqJsrr8Otd1E/x07po1LkUBmdAc5duPAg==", "dev": true, "license": "MIT", "dependencies": { @@ -4787,13 +5142,15 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-diff": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/fast-glob": { "version": "3.3.2", @@ -4836,28 +5193,30 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", - "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", "dev": true, - "license": "MIT" + "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==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fdir": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", - "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -4912,16 +5271,18 @@ } }, "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", "dev": true, + "license": "MIT", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4993,6 +5354,7 @@ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } @@ -5058,25 +5420,27 @@ } }, "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==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "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": ">=14.14" + "node": ">=10" } }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", @@ -5084,6 +5448,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -5097,6 +5462,7 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5119,6 +5485,7 @@ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -5137,6 +5504,7 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5146,6 +5514,7 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -5155,6 +5524,7 @@ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -5187,6 +5557,7 @@ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -5200,10 +5571,11 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", - "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "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==", "dev": true, + "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -5282,6 +5654,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -5289,6 +5662,15 @@ "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", @@ -5338,6 +5720,7 @@ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -5390,7 +5773,20 @@ "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=12" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5401,6 +5797,7 @@ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -5412,7 +5809,8 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", @@ -5448,6 +5846,7 @@ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5457,6 +5856,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5466,6 +5866,7 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -5478,6 +5879,7 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5490,6 +5892,7 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5502,6 +5905,7 @@ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -5516,6 +5920,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -5526,6 +5931,7 @@ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -5536,7 +5942,8 @@ "node_modules/hi-base32": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", - "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" + "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==", + "license": "MIT" }, "node_modules/highlight.js": { "version": "10.7.3", @@ -5552,6 +5959,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "license": "MIT", "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -5575,13 +5983,15 @@ "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/http-proxy-agent": { "version": "7.0.2", @@ -5638,13 +6048,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -5654,6 +6066,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -5665,6 +6078,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/import-from-esm": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz", @@ -5695,6 +6118,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -5731,6 +6155,7 @@ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5739,7 +6164,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ini": { "version": "4.1.1", @@ -5756,6 +6182,7 @@ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -5787,6 +6214,7 @@ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -5802,13 +6230,15 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" }, @@ -5821,6 +6251,7 @@ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -5837,6 +6268,7 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5845,12 +6277,16 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5861,6 +6297,7 @@ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", "dev": true, + "license": "MIT", "dependencies": { "is-typed-array": "^1.1.13" }, @@ -5876,6 +6313,7 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -5907,6 +6345,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5915,6 +6354,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -5924,6 +6364,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -5935,13 +6376,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5964,6 +6407,7 @@ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6002,6 +6446,7 @@ "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*" } @@ -6011,6 +6456,7 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -6027,6 +6473,7 @@ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7" }, @@ -6055,6 +6502,7 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6070,6 +6518,7 @@ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -6098,6 +6547,7 @@ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, + "license": "MIT", "dependencies": { "which-typed-array": "^1.1.14" }, @@ -6126,6 +6576,7 @@ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -6147,15 +6598,17 @@ } }, "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 + "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/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" }, "node_modules/issue-parser": { "version": "7.0.1", @@ -6179,6 +6632,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } @@ -6188,6 +6642,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -6217,6 +6672,7 @@ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -6263,29 +6719,34 @@ "node_modules/js-sha256": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.11.0.tgz", - "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==" + "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==", + "license": "MIT" }, "node_modules/js-sha3": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.3.tgz", - "integrity": "sha512-BcJPCQeLg6WjEx3FE591wVAevlli8lxsxm9/FzV4HXkV49TmBH38Yvrpce6fjbADGMKFrBMGTqrVz3qPIZ88Gg==" + "integrity": "sha512-BcJPCQeLg6WjEx3FE591wVAevlli8lxsxm9/FzV4HXkV49TmBH38Yvrpce6fjbADGMKFrBMGTqrVz3qPIZ88Gg==", + "license": "MIT" }, "node_modules/js-sha512": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.9.0.tgz", - "integrity": "sha512-mirki9WS/SUahm+1TbAPkqvbCiCfOAAsyXeHxK1UkullnJVVqoJG2pL9ObvT05CN+tM7fxhfYm0NbXn+1hWoZg==" + "integrity": "sha512-mirki9WS/SUahm+1TbAPkqvbCiCfOAAsyXeHxK1UkullnJVVqoJG2pL9ObvT05CN+tM7fxhfYm0NbXn+1hWoZg==", + "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -6297,6 +6758,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" } @@ -6312,18 +6774,20 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, @@ -6350,12 +6814,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stable-stringify/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" }, @@ -6434,6 +6892,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -6446,13 +6905,15 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -6468,6 +6929,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, + "license": "MIT", "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -6477,15 +6939,16 @@ } }, "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dev": true, + "license": "MIT", "dependencies": { - "p-locate": "^5.0.0" + "p-locate": "^6.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6523,7 +6986,8 @@ "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==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", @@ -6550,7 +7014,8 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.mergewith": { "version": "4.6.2", @@ -6577,7 +7042,8 @@ "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.uniq": { "version": "4.5.0", @@ -6608,18 +7074,18 @@ "license": "MIT" }, "node_modules/lru-cache": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz", - "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", "license": "ISC", "engines": { "node": "20 || >=22" } }, "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dev": true, "license": "MIT", "dependencies": { @@ -6627,13 +7093,14 @@ } }, "node_modules/magicast": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.4.tgz", - "integrity": "sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/parser": "^7.24.4", - "@babel/types": "^7.24.0", + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, @@ -6642,6 +7109,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -6666,37 +7134,25 @@ } }, "node_modules/marked-terminal": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.1.0.tgz", - "integrity": "sha512-+pvwa14KZL74MVXjYdPR3nSInhGhNvPce/3mqLVZT2oUvt654sL1XImFuLZ1pkA866IYZ3ikDTOFUIC7XzpZZg==", + "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==", "dev": true, "license": "MIT", "dependencies": { "ansi-escapes": "^7.0.0", + "ansi-regex": "^6.1.0", "chalk": "^5.3.0", "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", "node-emoji": "^2.1.3", - "supports-hyperlinks": "^3.0.0" + "supports-hyperlinks": "^3.1.0" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "marked": ">=1 <14" - } - }, - "node_modules/marked-terminal/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "marked": ">=1 <15" } }, "node_modules/memorystream": { @@ -6797,26 +7253,26 @@ "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" }, "node_modules/minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "license": "MIT" }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "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": "^2.0.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, "node_modules/minimist": { @@ -6843,6 +7299,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, + "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -6892,7 +7349,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/neo-async": { "version": "2.6.2", @@ -6912,7 +7370,8 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-emoji": { "version": "2.1.3", @@ -6935,6 +7394,7 @@ "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", "dev": true, + "license": "ISC", "dependencies": { "inherits": "^2.0.1", "readable-stream": "~1.0.31" @@ -6945,6 +7405,7 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -6957,6 +7418,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } @@ -6975,9 +7437,9 @@ } }, "node_modules/npm": { - "version": "10.8.3", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.3.tgz", - "integrity": "sha512-0IQlyAYvVtQ7uOhDFYZCGK8kkut2nh8cpAdA9E6FvRSJaTgtZRZgNjlC5ZCct//L73ygrpY93CxXpRJDtNqPVg==", + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.0.tgz", + "integrity": "sha512-ZanDioFylI9helNhl2LNd+ErmVD+H5I53ry41ixlLyCBgkuYb+58CvbAp99hW+zr5L9W4X7CchSoeqKdngOLSw==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -7059,18 +7521,18 @@ ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^7.5.4", - "@npmcli/config": "^8.3.4", - "@npmcli/fs": "^3.1.1", - "@npmcli/map-workspaces": "^3.0.6", - "@npmcli/package-json": "^5.2.0", - "@npmcli/promise-spawn": "^7.0.2", - "@npmcli/redact": "^2.0.1", - "@npmcli/run-script": "^8.1.0", + "@npmcli/arborist": "^8.0.0", + "@npmcli/config": "^9.0.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", + "@npmcli/promise-spawn": "^8.0.1", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", "@sigstore/tuf": "^2.3.4", - "abbrev": "^2.0.0", + "abbrev": "^3.0.0", "archy": "~1.0.0", - "cacache": "^18.0.4", + "cacache": "^19.0.1", "chalk": "^5.3.0", "ci-info": "^4.0.0", "cli-columns": "^4.0.0", @@ -7078,54 +7540,54 @@ "fs-minipass": "^3.0.3", "glob": "^10.4.5", "graceful-fs": "^4.2.11", - "hosted-git-info": "^7.0.2", - "ini": "^4.1.3", - "init-package-json": "^6.0.3", + "hosted-git-info": "^8.0.0", + "ini": "^5.0.0", + "init-package-json": "^7.0.1", "is-cidr": "^5.1.0", - "json-parse-even-better-errors": "^3.0.2", - "libnpmaccess": "^8.0.6", - "libnpmdiff": "^6.1.4", - "libnpmexec": "^8.1.4", - "libnpmfund": "^5.0.12", - "libnpmhook": "^10.0.5", - "libnpmorg": "^6.0.6", - "libnpmpack": "^7.0.4", - "libnpmpublish": "^9.0.9", - "libnpmsearch": "^7.0.6", - "libnpmteam": "^6.0.5", - "libnpmversion": "^6.0.3", - "make-fetch-happen": "^13.0.1", + "json-parse-even-better-errors": "^4.0.0", + "libnpmaccess": "^9.0.0", + "libnpmdiff": "^7.0.0", + "libnpmexec": "^9.0.0", + "libnpmfund": "^6.0.0", + "libnpmhook": "^11.0.0", + "libnpmorg": "^7.0.0", + "libnpmpack": "^8.0.0", + "libnpmpublish": "^10.0.0", + "libnpmsearch": "^8.0.0", + "libnpmteam": "^7.0.0", + "libnpmversion": "^7.0.0", + "make-fetch-happen": "^14.0.1", "minimatch": "^9.0.5", "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", "node-gyp": "^10.2.0", - "nopt": "^7.2.1", - "normalize-package-data": "^6.0.2", - "npm-audit-report": "^5.0.0", - "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.3", - "npm-pick-manifest": "^9.1.0", - "npm-profile": "^10.0.0", - "npm-registry-fetch": "^17.1.0", - "npm-user-validate": "^2.0.1", + "nopt": "^8.0.0", + "normalize-package-data": "^7.0.0", + "npm-audit-report": "^6.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-profile": "^11.0.1", + "npm-registry-fetch": "^18.0.1", + "npm-user-validate": "^3.0.0", "p-map": "^4.0.0", - "pacote": "^18.0.6", - "parse-conflict-json": "^3.0.1", - "proc-log": "^4.2.0", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", "qrcode-terminal": "^0.12.0", - "read": "^3.0.1", + "read": "^4.0.0", "semver": "^7.6.3", "spdx-expression-parse": "^4.0.0", - "ssri": "^10.0.6", + "ssri": "^12.0.0", "supports-color": "^9.4.0", "tar": "^6.2.1", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", - "validate-npm-package-name": "^5.0.1", - "which": "^4.0.0", - "write-file-atomic": "^5.0.1" + "validate-npm-package-name": "^6.0.0", + "which": "^5.0.0", + "write-file-atomic": "^6.0.0" }, "bin": { "npm": "bin/npm-cli.js", @@ -7140,6 +7602,7 @@ "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "chalk": "^2.4.1", @@ -7160,33 +7623,12 @@ "node": ">= 4" } }, - "node_modules/npm-run-all/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "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, - "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", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -7196,26 +7638,12 @@ "node": ">=4" } }, - "node_modules/npm-run-all/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/npm-run-all/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, "node_modules/npm-run-all/node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, + "license": "MIT", "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -7232,6 +7660,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -7241,27 +7670,17 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "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, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/npm-run-all/node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -7271,6 +7690,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } @@ -7280,6 +7700,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^1.0.0" }, @@ -7292,6 +7713,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7301,6 +7723,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -7313,6 +7736,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -7430,6 +7854,18 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/npm/node_modules/@isaacs/string-locale-compare": { "version": "1.1.0", "dev": true, @@ -7437,7 +7873,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { - "version": "2.2.2", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -7449,48 +7885,48 @@ "socks-proxy-agent": "^8.0.3" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.5.4", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.1", - "@npmcli/installed-package-contents": "^2.1.0", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.1.1", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.1.0", - "@npmcli/query": "^3.1.0", - "@npmcli/redact": "^2.0.0", - "@npmcli/run-script": "^8.1.0", - "bin-links": "^4.0.4", - "cacache": "^18.0.3", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/metavuln-calculator": "^8.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.1", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "bin-links": "^5.0.0", + "cacache": "^19.0.1", "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^7.0.2", - "json-parse-even-better-errors": "^3.0.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", "json-stringify-nice": "^1.1.4", "lru-cache": "^10.2.2", "minimatch": "^9.0.4", - "nopt": "^7.2.1", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.2", - "npm-pick-manifest": "^9.0.1", - "npm-registry-fetch": "^17.0.1", - "pacote": "^18.0.6", - "parse-conflict-json": "^3.0.0", - "proc-log": "^4.2.0", - "proggy": "^2.0.0", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.1", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", - "read-package-json-fast": "^3.0.2", + "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", - "ssri": "^10.0.6", + "ssri": "^12.0.0", "treeverse": "^3.0.0", "walk-up-path": "^3.0.1" }, @@ -7498,30 +7934,30 @@ "arborist": "bin/index.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.3.4", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/package-json": "^5.1.1", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", "ci-info": "^4.0.0", - "ini": "^4.1.2", - "nopt": "^7.2.1", - "proc-log": "^4.2.0", + "ini": "^5.0.0", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", "walk-up-path": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/fs": { - "version": "3.1.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -7529,160 +7965,160 @@ "semver": "^7.3.5" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "5.0.8", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", - "ini": "^4.1.3", + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^4.0.0", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", - "which": "^4.0.0" + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "2.1.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" }, "bin": { "installed-package-contents": "bin/index.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "3.0.6", + "version": "4.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/package-json": "^6.0.0", "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" + "minimatch": "^9.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "7.1.1", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cacache": "^18.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^18.0.0", - "proc-log": "^4.1.0", + "cacache": "^19.0.0", + "json-parse-even-better-errors": "^4.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "3.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "5.2.0", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.0", + "@npmcli/git": "^6.0.0", "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^4.0.0", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "normalize-package-data": "^7.0.0", + "proc-log": "^5.0.0", "semver": "^7.5.3" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "7.0.2", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "which": "^4.0.0" + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/query": { - "version": "3.1.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.10" + "postcss-selector-parser": "^6.1.2" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/redact": { - "version": "2.0.1", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "8.1.0", + "version": "9.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", "node-gyp": "^10.0.0", - "proc-log": "^4.0.0", - "which": "^4.0.0" + "proc-log": "^5.0.0", + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@pkgjs/parseargs": { @@ -7742,6 +8178,142 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/@npmcli/agent": { + "version": "2.2.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/@npmcli/fs": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/cacache": { + "version": "18.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/make-fetch-happen": { + "version": "13.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/minipass-fetch": { + "version": "3.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/proc-log": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/ssri": { + "version": "10.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/unique-filename": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/unique-slug": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/npm/node_modules/@sigstore/tuf": { "version": "2.3.4", "dev": true, @@ -7792,12 +8364,12 @@ } }, "node_modules/npm/node_modules/abbrev": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/agent-base": { @@ -7865,18 +8437,19 @@ "license": "MIT" }, "node_modules/npm/node_modules/bin-links": { - "version": "4.0.4", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/binary-extensions": { @@ -7901,12 +8474,12 @@ } }, "node_modules/npm/node_modules/cacache": { - "version": "18.0.4", + "version": "19.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/fs": "^3.1.0", + "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", @@ -7914,13 +8487,88 @@ "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/minizlib": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/p-map": { + "version": "7.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" } }, "node_modules/npm/node_modules/chalk": { @@ -7994,12 +8642,12 @@ } }, "node_modules/npm/node_modules/cmd-shim": { - "version": "6.0.3", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/color-convert": { @@ -8206,7 +8854,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "7.0.2", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -8214,7 +8862,7 @@ "lru-cache": "^10.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/http-cache-semantics": { @@ -8263,7 +8911,7 @@ } }, "node_modules/npm/node_modules/ignore-walk": { - "version": "6.0.5", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -8271,7 +8919,7 @@ "minimatch": "^9.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/imurmurhash": { @@ -8293,30 +8941,30 @@ } }, "node_modules/npm/node_modules/ini": { - "version": "4.1.3", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/init-package-json": { - "version": "6.0.3", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/package-json": "^5.0.0", - "npm-package-arg": "^11.0.0", - "promzard": "^1.0.0", - "read": "^3.0.1", + "@npmcli/package-json": "^6.0.0", + "npm-package-arg": "^12.0.0", + "promzard": "^2.0.0", + "read": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" + "validate-npm-package-name": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/ip-address": { @@ -8399,12 +9047,12 @@ "license": "MIT" }, "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "3.0.2", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/json-stringify-nice": { @@ -8438,169 +9086,169 @@ "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.6", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-package-arg": "^11.0.2", - "npm-registry-fetch": "^17.0.1" + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.1.4", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4", - "@npmcli/installed-package-contents": "^2.1.0", + "@npmcli/arborist": "^8.0.0", + "@npmcli/installed-package-contents": "^3.0.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", "minimatch": "^9.0.4", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", "tar": "^6.2.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "8.1.4", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4", - "@npmcli/run-script": "^8.1.0", + "@npmcli/arborist": "^8.0.0", + "@npmcli/run-script": "^9.0.1", "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6", - "proc-log": "^4.2.0", - "read": "^3.0.1", - "read-package-json-fast": "^3.0.2", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", + "read": "^4.0.0", + "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", "walk-up-path": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.12", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4" + "@npmcli/arborist": "^8.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmhook": { - "version": "10.0.5", + "version": "11.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.6", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "7.0.4", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4", - "@npmcli/run-script": "^8.1.0", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6" + "@npmcli/arborist": "^8.0.0", + "@npmcli/run-script": "^9.0.1", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.9", + "version": "10.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "ci-info": "^4.0.0", - "normalize-package-data": "^6.0.1", - "npm-package-arg": "^11.0.2", - "npm-registry-fetch": "^17.0.1", - "proc-log": "^4.2.0", + "normalize-package-data": "^7.0.0", + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1", + "proc-log": "^5.0.0", "semver": "^7.3.7", "sigstore": "^2.2.0", - "ssri": "^10.0.6" + "ssri": "^12.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmsearch": { - "version": "7.0.6", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmteam": { - "version": "6.0.5", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmversion": { - "version": "6.0.3", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.7", - "@npmcli/run-script": "^8.1.0", - "json-parse-even-better-errors": "^3.0.2", - "proc-log": "^4.2.0", + "@npmcli/git": "^6.0.1", + "@npmcli/run-script": "^9.0.1", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.7" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/lru-cache": { @@ -8610,26 +9258,25 @@ "license": "ISC" }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "13.0.1", + "version": "14.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", + "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", - "proc-log": "^4.2.0", + "proc-log": "^5.0.0", "promise-retry": "^2.0.1", - "ssri": "^10.0.0" + "ssri": "^12.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/minimatch": { @@ -8669,22 +9316,35 @@ } }, "node_modules/npm/node_modules/minipass-fetch": { - "version": "3.0.5", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" + "minizlib": "^3.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" }, "optionalDependencies": { "encoding": "^0.1.13" } }, + "node_modules/npm/node_modules/minipass-fetch/node_modules/minizlib": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/npm/node_modules/minipass-flush": { "version": "1.0.5", "dev": true, @@ -8801,49 +9461,233 @@ "license": "MIT" }, "node_modules/npm/node_modules/mute-stream": { - "version": "1.0.0", + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/negotiator": { "version": "0.6.3", "dev": true, "inBundle": true, - "license": "MIT", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "10.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/@npmcli/agent": { + "version": "2.2.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/@npmcli/fs": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/abbrev": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/cacache": { + "version": "18.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/make-fetch-happen": { + "version": "13.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/minipass-fetch": { + "version": "3.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/nopt": { + "version": "7.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/ssri": { + "version": "10.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/unique-filename": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/unique-slug": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, "engines": { - "node": ">= 0.6" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/node-gyp": { - "version": "10.2.0", + "node_modules/npm/node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^4.1.0", - "semver": "^7.3.5", - "tar": "^6.2.1", - "which": "^4.0.0" + "isexe": "^3.1.1" }, "bin": { - "node-gyp": "bin/node-gyp.js" + "node-which": "bin/which.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" } }, "node_modules/npm/node_modules/nopt": { - "version": "7.2.1", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -8853,47 +9697,56 @@ "bin": { "nopt": "bin/nopt.js" }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/nopt/node_modules/abbrev": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/npm/node_modules/normalize-package-data": { - "version": "6.0.2", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "hosted-git-info": "^7.0.0", + "hosted-git-info": "^8.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-audit-report": { - "version": "5.0.0", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-bundled": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-normalize-package-bin": "^3.0.0" + "npm-normalize-package-bin": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-install-checks": { - "version": "6.3.0", + "version": "7.1.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -8901,99 +9754,112 @@ "semver": "^7.1.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.3", + "version": "12.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" + "validate-npm-package-name": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-packlist": { - "version": "8.0.2", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "ignore-walk": "^6.0.4" + "ignore-walk": "^7.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "9.1.0", + "version": "10.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-profile": { - "version": "10.0.0", + "version": "11.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^17.0.1", - "proc-log": "^4.0.0" + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0" }, "engines": { - "node": ">=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "17.1.0", + "version": "18.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/redact": "^2.0.0", + "@npmcli/redact": "^3.0.0", "jsonparse": "^1.3.1", - "make-fetch-happen": "^13.0.0", + "make-fetch-happen": "^14.0.0", "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^4.0.0" + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch/node_modules/minizlib": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" } }, "node_modules/npm/node_modules/npm-user-validate": { - "version": "2.0.1", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/p-map": { @@ -9018,48 +9884,48 @@ "license": "BlueOak-1.0.0" }, "node_modules/npm/node_modules/pacote": { - "version": "18.0.6", + "version": "19.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/package-json": "^5.1.0", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^8.0.0", - "cacache": "^18.0.0", + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^17.0.0", - "proc-log": "^4.0.0", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "sigstore": "^2.2.0", - "ssri": "^10.0.0", + "ssri": "^12.0.0", "tar": "^6.1.11" }, "bin": { "pacote": "bin/index.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/parse-conflict-json": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", + "json-parse-even-better-errors": "^4.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/path-key": { @@ -9101,21 +9967,21 @@ } }, "node_modules/npm/node_modules/proc-log": { - "version": "4.2.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/proggy": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/promise-all-reject-late": { @@ -9156,15 +10022,15 @@ } }, "node_modules/npm/node_modules/promzard": { - "version": "1.0.2", + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "read": "^3.0.1" + "read": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/qrcode-terminal": { @@ -9176,37 +10042,37 @@ } }, "node_modules/npm/node_modules/read": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "mute-stream": "^1.0.0" + "mute-stream": "^2.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/read-cmd-shim": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/read-package-json-fast": { - "version": "3.0.2", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/retry": { @@ -9218,6 +10084,21 @@ "node": ">= 4" } }, + "node_modules/npm/node_modules/rimraf": { + "version": "5.0.10", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/npm/node_modules/safer-buffer": { "version": "2.1.2", "dev": true, @@ -9374,7 +10255,7 @@ "license": "BSD-3-Clause" }, "node_modules/npm/node_modules/ssri": { - "version": "10.0.6", + "version": "12.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -9382,7 +10263,7 @@ "minipass": "^7.0.3" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/string-width": { @@ -9465,91 +10346,227 @@ "yallist": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=10" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "2.0.1", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/@npmcli/agent": { + "version": "2.2.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/@npmcli/fs": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/cacache": { + "version": "18.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", + "node_modules/npm/node_modules/tuf-js/node_modules/make-fetch-happen": { + "version": "13.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "minipass": "^3.0.0" + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" }, "engines": { - "node": ">= 8" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", + "node_modules/npm/node_modules/tuf-js/node_modules/minipass-fetch": { + "version": "3.0.5", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" }, "engines": { - "node": ">=8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" } }, - "node_modules/npm/node_modules/tar/node_modules/minipass": { - "version": "5.0.0", + "node_modules/npm/node_modules/tuf-js/node_modules/proc-log": { + "version": "4.2.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": ">=8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/tiny-relative-date": { - "version": "1.3.0", + "node_modules/npm/node_modules/tuf-js/node_modules/ssri": { + "version": "10.0.6", "dev": true, "inBundle": true, - "license": "MIT" + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "node_modules/npm/node_modules/treeverse": { + "node_modules/npm/node_modules/tuf-js/node_modules/unique-filename": { "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/tuf-js": { - "version": "2.2.1", + "node_modules/npm/node_modules/tuf-js/node_modules/unique-slug": { + "version": "4.0.0", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@tufjs/models": "2.0.1", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.1" + "imurmurhash": "^0.1.4" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/npm/node_modules/unique-filename": { - "version": "3.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "unique-slug": "^4.0.0" + "unique-slug": "^5.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/unique-slug": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -9557,7 +10574,7 @@ "imurmurhash": "^0.1.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/util-deprecate": { @@ -9587,12 +10604,12 @@ } }, "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "5.0.1", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/walk-up-path": { @@ -9602,7 +10619,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/which": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -9613,7 +10630,7 @@ "node-which": "bin/which.js" }, "engines": { - "node": "^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/which/node_modules/isexe": { @@ -9726,7 +10743,7 @@ } }, "node_modules/npm/node_modules/write-file-atomic": { - "version": "5.0.1", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -9735,7 +10752,7 @@ "signal-exit": "^4.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/yallist": { @@ -9755,10 +10772,14 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9768,6 +10789,7 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -9777,6 +10799,7 @@ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -9795,6 +10818,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -9837,6 +10861,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -9899,30 +10924,32 @@ } }, "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "dev": true, + "license": "MIT", "dependencies": { - "yocto-queue": "^0.1.0" + "yocto-queue": "^1.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", "dev": true, + "license": "MIT", "dependencies": { - "p-limit": "^3.0.2" + "p-limit": "^4.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9965,9 +10992,9 @@ } }, "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { @@ -9975,6 +11002,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -9987,6 +11015,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -10068,33 +11097,59 @@ "npm": ">5" } }, - "node_modules/patch-package/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==", + "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": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/patch-package/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==", + "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": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "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", @@ -10117,19 +11172,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/patch-package/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/patch-package/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -10144,23 +11186,14 @@ "rimraf": "bin.js" } }, - "node_modules/patch-package/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/path-is-absolute": { @@ -10168,6 +11201,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10176,6 +11210,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", "engines": { "node": ">=8" } @@ -10184,7 +11219,8 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-scurry": { "version": "2.0.0", @@ -10203,13 +11239,16 @@ } }, "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/pathe": { @@ -10230,10 +11269,11 @@ } }, "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.2", @@ -10241,8 +11281,6 @@ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=12" }, @@ -10255,6 +11293,7 @@ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", "dev": true, + "license": "MIT", "bin": { "pidtree": "bin/pidtree.js" }, @@ -10267,6 +11306,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -10362,6 +11402,7 @@ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -10400,6 +11441,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -10425,6 +11467,7 @@ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, + "license": "MIT", "dependencies": { "fast-diff": "^1.1.2" }, @@ -10452,7 +11495,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/proto-list": { "version": "1.2.4", @@ -10466,6 +11510,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -10488,7 +11533,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/rc": { "version": "1.2.8", @@ -10619,6 +11665,7 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "dev": true, + "license": "MIT", "dependencies": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -10628,23 +11675,12 @@ "node": ">=4" } }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -10652,16 +11688,24 @@ "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/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "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==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -10688,6 +11732,7 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10697,6 +11742,7 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10706,6 +11752,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -10719,12 +11766,13 @@ } }, "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/resolve-pkg-maps": { @@ -10732,6 +11780,7 @@ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -10741,6 +11790,7 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -10767,9 +11817,9 @@ } }, "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", + "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", "dev": true, "license": "MIT", "dependencies": { @@ -10783,22 +11833,24 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", + "@rollup/rollup-android-arm-eabi": "4.24.3", + "@rollup/rollup-android-arm64": "4.24.3", + "@rollup/rollup-darwin-arm64": "4.24.3", + "@rollup/rollup-darwin-x64": "4.24.3", + "@rollup/rollup-freebsd-arm64": "4.24.3", + "@rollup/rollup-freebsd-x64": "4.24.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", + "@rollup/rollup-linux-arm-musleabihf": "4.24.3", + "@rollup/rollup-linux-arm64-gnu": "4.24.3", + "@rollup/rollup-linux-arm64-musl": "4.24.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", + "@rollup/rollup-linux-riscv64-gnu": "4.24.3", + "@rollup/rollup-linux-s390x-gnu": "4.24.3", + "@rollup/rollup-linux-x64-gnu": "4.24.3", + "@rollup/rollup-linux-x64-musl": "4.24.3", + "@rollup/rollup-win32-arm64-msvc": "4.24.3", + "@rollup/rollup-win32-ia32-msvc": "4.24.3", + "@rollup/rollup-win32-x64-msvc": "4.24.3", "fsevents": "~2.3.2" } }, @@ -10821,6 +11873,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -10830,6 +11883,7 @@ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -10843,23 +11897,19 @@ "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 - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/safe-regex-test": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -10873,9 +11923,9 @@ } }, "node_modules/semantic-release": { - "version": "24.1.2", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.1.2.tgz", - "integrity": "sha512-hvEJ7yI97pzJuLsDZCYzJgmRxF8kiEJvNZhf0oiZQcexw+Ycjy4wbdsn/sVMURgNCu8rwbAXJdBRyIxM4pe32g==", + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.0.tgz", + "integrity": "sha512-fQfn6e/aYToRtVJYKqneFM1Rg3KP2gh3wSWtpYsLlz6uaPKlISrTzvYAFn+mYWo07F0X1Cz5ucU89AVE8X1mbg==", "dev": true, "license": "MIT", "dependencies": { @@ -10916,21 +11966,6 @@ "node": ">=20.8.1" } }, - "node_modules/semantic-release/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/semantic-release/node_modules/hosted-git-info": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.0.tgz", @@ -10951,45 +11986,6 @@ "dev": true, "license": "ISC" }, - "node_modules/semantic-release/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/semantic-release/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/semantic-release/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -11037,6 +12033,7 @@ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -11054,6 +12051,7 @@ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -11068,6 +12066,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -11079,6 +12078,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", "engines": { "node": ">=8" } @@ -11088,6 +12088,7 @@ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11097,6 +12098,7 @@ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -11144,19 +12146,6 @@ "node": ">=6" } }, - "node_modules/signale/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/signale/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -11172,23 +12161,6 @@ "node": ">=4" } }, - "node_modules/signale/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/signale/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, "node_modules/signale/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -11249,16 +12221,13 @@ } }, "node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true, "license": "MIT", "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, "node_modules/slice-ansi": { @@ -11266,6 +12235,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -11278,6 +12248,42 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/slice-ansi/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/slice-ansi/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/slice-ansi/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/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -11293,6 +12299,7 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -11309,6 +12316,7 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -11318,23 +12326,26 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true + "dev": true, + "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, + "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", - "dev": true + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true, + "license": "CC0-1.0" }, "node_modules/split2": { "version": "4.2.0", @@ -11408,19 +12419,24 @@ "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/string-width-cjs": { @@ -11438,11 +12454,39 @@ "node": ">=8" } }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.padend": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -11461,6 +12505,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -11479,6 +12524,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -11493,6 +12539,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -11506,14 +12553,18 @@ } }, "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/strip-ansi-cjs": { @@ -11529,11 +12580,21 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -11586,6 +12647,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -11615,6 +12677,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -11623,10 +12686,11 @@ } }, "node_modules/synckit": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", - "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", "dev": true, + "license": "MIT", "dependencies": { "@pkgr/core": "^0.1.0", "tslib": "^2.6.2" @@ -11643,39 +12707,63 @@ "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=8" } }, - "node_modules/table/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "node_modules/table/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "ansi-regex": "^5.0.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">=8" } }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/temp-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", @@ -11746,6 +12834,16 @@ "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", @@ -11790,6 +12888,22 @@ "dev": true, "license": "ISC" }, + "node_modules/test-exclude/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/test-exclude/node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -11824,7 +12938,8 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/thenify": { "version": "3.3.1", @@ -11861,6 +12976,7 @@ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -11870,13 +12986,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/through2/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -11892,6 +13010,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -11920,9 +13039,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz", - "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", "dev": true, "license": "MIT" }, @@ -11969,15 +13088,6 @@ "node": ">=0.6.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -12005,9 +13115,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", + "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", "dev": true, "license": "MIT", "engines": { @@ -12018,9 +13128,10 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/tsx": { "version": "4.19.1", @@ -12045,13 +13156,15 @@ "node_modules/tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "license": "Unlicense" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -12077,6 +13190,7 @@ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -12091,6 +13205,7 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -12110,6 +13225,7 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -12130,6 +13246,7 @@ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -12146,9 +13263,9 @@ } }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -12178,6 +13295,7 @@ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -12256,6 +13374,7 @@ "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -12275,6 +13394,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -12293,22 +13413,24 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, + "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "node_modules/vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", + "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12885,12 +14007,14 @@ "node_modules/vlq": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", - "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==" + "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==", + "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==", + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -12906,6 +14030,7 @@ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -12922,6 +14047,7 @@ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -12958,6 +14084,7 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12970,17 +14097,17 @@ "license": "MIT" }, "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -13004,17 +14131,105 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4" } @@ -13024,14 +14239,15 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", "dev": true, "license": "ISC", "bin": { @@ -13042,39 +14258,87 @@ } }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { - "node": ">=10" + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" diff --git a/package.json b/package.json index 3da2f34..74f4fcb 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.15", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.14", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.24", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index c8f2601..d3043d6 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -34,7 +34,7 @@ export class SourceFileVisitor { } }, sourceLocation(node: ts.Node): SourceLocation { - return SourceLocation.fromNode(sourceFile, node, program.getCurrentDirectory()) + return SourceLocation.fromNode(node, program.getCurrentDirectory()) }, } } From ffff35edb62c87050cb8b0bf40faf38091fc3cb2 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 1 Nov 2024 18:06:23 +0800 Subject: [PATCH 45/85] refactor: rename test artifacts folder name for consistency --- .../data/PrimitiveOpsContract.approval.teal | 0 .../data/PrimitiveOpsContract.arc32.json | 0 .../data/PrimitiveOpsContract.clear.teal | 0 tests/primitives/biguint.spec.ts | 2 +- tests/primitives/bytes.spec.ts | 2 +- tests/primitives/uint64.spec.ts | 2 +- 6 files changed, 3 insertions(+), 3 deletions(-) rename tests/artifacts/{primitives => primitive-ops}/data/PrimitiveOpsContract.approval.teal (100%) rename tests/artifacts/{primitives => primitive-ops}/data/PrimitiveOpsContract.arc32.json (100%) rename tests/artifacts/{primitives => primitive-ops}/data/PrimitiveOpsContract.clear.teal (100%) diff --git a/tests/artifacts/primitives/data/PrimitiveOpsContract.approval.teal b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal similarity index 100% rename from tests/artifacts/primitives/data/PrimitiveOpsContract.approval.teal rename to tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal diff --git a/tests/artifacts/primitives/data/PrimitiveOpsContract.arc32.json b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json similarity index 100% rename from tests/artifacts/primitives/data/PrimitiveOpsContract.arc32.json rename to tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json diff --git a/tests/artifacts/primitives/data/PrimitiveOpsContract.clear.teal b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.clear.teal similarity index 100% rename from tests/artifacts/primitives/data/PrimitiveOpsContract.clear.teal rename to tests/artifacts/primitive-ops/data/PrimitiveOpsContract.clear.teal diff --git a/tests/primitives/biguint.spec.ts b/tests/primitives/biguint.spec.ts index 4b3833a..894d268 100644 --- a/tests/primitives/biguint.spec.ts +++ b/tests/primitives/biguint.spec.ts @@ -5,7 +5,7 @@ import type { biguint } from '@algorandfoundation/algorand-typescript' import { BigUint, Bytes, internal, Uint64 } from '@algorandfoundation/algorand-typescript' import { describe, expect, it } from 'vitest' import { BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE, MAX_UINT512, MAX_UINT64 } from '../../src/constants' -import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' +import appSpecJson from '../artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' import { abiAsBytes } from '../util' diff --git a/tests/primitives/bytes.spec.ts b/tests/primitives/bytes.spec.ts index a76d013..5a5b59f 100644 --- a/tests/primitives/bytes.spec.ts +++ b/tests/primitives/bytes.spec.ts @@ -3,7 +3,7 @@ import { bytes, Bytes, internal } from '@algorandfoundation/algorand-typescript' import { describe, expect, it } from 'vitest' import { MAX_BYTES_SIZE } from '../../src/constants' import { sha256 } from '../../src/impl' -import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' +import appSpecJson from '../artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' import { asUint8Array, getSha256Hash, padUint8Array } from '../util' diff --git a/tests/primitives/uint64.spec.ts b/tests/primitives/uint64.spec.ts index 9d5bc59..c5abea8 100644 --- a/tests/primitives/uint64.spec.ts +++ b/tests/primitives/uint64.spec.ts @@ -2,7 +2,7 @@ import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { internal, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { describe, expect, it } from 'vitest' import { UINT64_OVERFLOW_UNDERFLOW_MESSAGE } from '../../src/constants' -import appSpecJson from '../artifacts/primitives/data/PrimitiveOpsContract.arc32.json' +import appSpecJson from '../artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' const MAX_UINT64 = 2n ** 64n - 1n From 11e3df1a6b598b0355b2c567b0d5d996e58d58d5 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 1 Nov 2024 18:07:22 +0800 Subject: [PATCH 46/85] refactor: use new enum export without op namespace --- src/impl/crypto.ts | 16 ++++++------- src/impl/pure.ts | 6 ++--- tests/crypto-op-codes.spec.ts | 42 ++++++++++++++++------------------- tests/pure-op-codes.spec.ts | 10 ++++----- 4 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/impl/crypto.ts b/src/impl/crypto.ts index be9ef02..7cdbd46 100644 --- a/src/impl/crypto.ts +++ b/src/impl/crypto.ts @@ -1,4 +1,4 @@ -import { arc4, bytes, Bytes, gtxn, internal } from '@algorandfoundation/algorand-typescript' +import { arc4, bytes, Bytes, Ecdsa, gtxn, internal, VrfVerify } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' import { ec } from 'elliptic' import { sha256 as js_sha256 } from 'js-sha256' @@ -68,7 +68,7 @@ export const ed25519verify = ( } export const ecdsaVerify = ( - v: internal.opTypes.Ecdsa, + v: Ecdsa, a: internal.primitives.StubBytesCompat, b: internal.primitives.StubBytesCompat, c: internal.primitives.StubBytesCompat, @@ -91,13 +91,13 @@ export const ecdsaVerify = ( } export const ecdsaPkRecover = ( - v: internal.opTypes.Ecdsa, + v: Ecdsa, a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat, c: internal.primitives.StubBytesCompat, d: internal.primitives.StubBytesCompat, ): readonly [bytes, bytes] => { - if (v !== internal.opTypes.Ecdsa.Secp256k1) { + if (v !== Ecdsa.Secp256k1) { internal.errors.internalError(`Unsupported ECDSA curve: ${v}`) } const dataBytes = internal.primitives.BytesCls.fromCompat(a) @@ -117,7 +117,7 @@ export const ecdsaPkRecover = ( return [Bytes(x), Bytes(y)] } -export const ecdsaPkDecompress = (v: internal.opTypes.Ecdsa, a: internal.primitives.StubBytesCompat): readonly [bytes, bytes] => { +export const ecdsaPkDecompress = (v: Ecdsa, a: internal.primitives.StubBytesCompat): readonly [bytes, bytes] => { const bytesA = internal.primitives.BytesCls.fromCompat(a) const ecdsa = new ec(curveMap[v]) @@ -130,7 +130,7 @@ export const ecdsaPkDecompress = (v: internal.opTypes.Ecdsa, a: internal.primiti } export const vrfVerify = ( - _s: internal.opTypes.VrfVerify, + _s: VrfVerify, _a: internal.primitives.StubBytesCompat, _b: internal.primitives.StubBytesCompat, _c: internal.primitives.StubBytesCompat, @@ -145,6 +145,6 @@ export const EllipticCurve = new Proxy({} as internal.opTypes.EllipticCurveType, }) const curveMap = { - [internal.opTypes.Ecdsa.Secp256k1]: 'secp256k1', - [internal.opTypes.Ecdsa.Secp256r1]: 'p256', + [Ecdsa.Secp256k1]: 'secp256k1', + [Ecdsa.Secp256r1]: 'p256', } diff --git a/src/impl/pure.ts b/src/impl/pure.ts index 725e24c..6d655f7 100644 --- a/src/impl/pure.ts +++ b/src/impl/pure.ts @@ -1,4 +1,4 @@ -import { biguint, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { Base64, biguint, Bytes, bytes, internal, Uint64, uint64 } 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 { asBigUint, asBytes, asMaybeBytesCls, asMaybeUint64Cls, asUint64Cls, binaryStringToBytes } from '../util' @@ -10,8 +10,8 @@ export const addw = (a: internal.primitives.StubUint64Compat, b: internal.primit return toUint128(sum) } -export const base64Decode = (e: internal.opTypes.Base64, a: internal.primitives.StubBytesCompat): bytes => { - const encoding = e === internal.opTypes.Base64.StdEncoding ? 'base64' : 'base64url' +export const base64Decode = (e: Base64, a: internal.primitives.StubBytesCompat): bytes => { + const encoding = e === Base64.StdEncoding ? 'base64' : 'base64url' const bytesValue = internal.primitives.BytesCls.fromCompat(a) const stringValue = bytesValue.toString() diff --git a/tests/crypto-op-codes.spec.ts b/tests/crypto-op-codes.spec.ts index 847152c..09a4995 100644 --- a/tests/crypto-op-codes.spec.ts +++ b/tests/crypto-op-codes.spec.ts @@ -1,6 +1,6 @@ import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { Bytes, internal, op as publicOps, uint64 } from '@algorandfoundation/algorand-typescript' +import { Bytes, Ec, Ecdsa, internal, uint64, VrfVerify } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' import { ec } from 'elliptic' import { keccak256 as js_keccak256 } from 'js-sha3' @@ -15,8 +15,8 @@ import { asUint8Array, getPaddedBytes } from './util' const MAX_ARG_LEN = 2048 const curveMap = { - [internal.opTypes.Ecdsa.Secp256k1]: 'secp256k1', - [internal.opTypes.Ecdsa.Secp256r1]: 'p256', + [Ecdsa.Secp256k1]: 'secp256k1', + [Ecdsa.Secp256r1]: 'p256', } vi.mock('../src/impl/crypto', async (importOriginal) => { @@ -157,7 +157,7 @@ describe('crypto op codes', async () => { asUint8Array(pubkeyX), asUint8Array(pubkeyY), ) - const result = op.ecdsaVerify(internal.opTypes.Ecdsa.Secp256k1, messageHash, sigR, sigS, pubkeyX, pubkeyY) + const result = op.ecdsaVerify(Ecdsa.Secp256k1, messageHash, sigR, sigS, pubkeyX, pubkeyY) expect(result).toEqual(avmResult) }) @@ -177,7 +177,7 @@ describe('crypto op codes', async () => { asUint8Array(pubkeyX), asUint8Array(pubkeyY), ) - const result = op.ecdsaVerify(internal.opTypes.Ecdsa.Secp256r1, messageHash, sigR, sigS, pubkeyX, pubkeyY) + const result = op.ecdsaVerify(Ecdsa.Secp256r1, messageHash, sigR, sigS, pubkeyX, pubkeyY) expect(result).toEqual(avmResult) }) @@ -185,7 +185,7 @@ describe('crypto op codes', async () => { describe('ecdsaPkRecover', async () => { it('should be able to recover k1 public key', async () => { - const testData = generateEcdsaTestData(internal.opTypes.Ecdsa.Secp256k1) + const testData = generateEcdsaTestData(Ecdsa.Secp256k1) const a = testData.data const b = testData.recoveryId const c = testData.r @@ -198,14 +198,14 @@ describe('crypto op codes', async () => { asUint8Array(c), asUint8Array(d), ) - const result = op.ecdsaPkRecover(internal.opTypes.Ecdsa.Secp256k1, a, b, c, d) + const result = op.ecdsaPkRecover(Ecdsa.Secp256k1, a, b, c, 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 () => { - const testData = generateEcdsaTestData(internal.opTypes.Ecdsa.Secp256r1) + const testData = generateEcdsaTestData(Ecdsa.Secp256r1) const a = testData.data const b = testData.recoveryId const c = testData.r @@ -221,13 +221,13 @@ describe('crypto op codes', async () => { ), ).rejects.toThrow('unsupported curve') - expect(() => op.ecdsaPkRecover(internal.opTypes.Ecdsa.Secp256r1, a, b, c, d)).toThrow('Unsupported ECDSA curve') + expect(() => op.ecdsaPkRecover(Ecdsa.Secp256r1, a, b, c, d)).toThrow('Unsupported ECDSA curve') }) }) describe('ecdsaPkDecompress', async () => { it('should be able to decompress k1 public key', async () => { - const v = internal.opTypes.Ecdsa.Secp256k1 + const v = Ecdsa.Secp256k1 const testData = generateEcdsaTestData(v) const ecdsa = new ec(curveMap[v]) const keyPair = ecdsa.keyFromPublic(testData.pubkeyX.concat(testData.pubkeyY).asUint8Array()) @@ -252,7 +252,7 @@ describe('crypto op codes', async () => { const c = internal.primitives.BytesCls.fromHex('3a2740da7a0788ebb12a52154acbcca1813c128ca0b249e93f8eb6563fee418d') it('should throw not available error', async () => { - expect(() => op.vrfVerify(internal.opTypes.VrfVerify.VrfAlgorand, a, b, c)).toThrow('vrfVerify is not available in test context') + expect(() => op.vrfVerify(VrfVerify.VrfAlgorand, a, b, c)).toThrow('vrfVerify is not available in test context') }) it('should return mocked result', async () => { @@ -265,7 +265,7 @@ describe('crypto op codes', async () => { ) 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(publicOps.VrfVerify.VrfAlgorand, a, b, c) + const result = mockedVrfVerify(VrfVerify.VrfAlgorand, a, b, c) expect(asUint8Array(result[0])).toEqual(new Uint8Array(avmResult[0])) expect(result[1]).toEqual(avmResult[1]) @@ -274,29 +274,25 @@ describe('crypto op codes', async () => { describe('EllipticCurve', async () => { it('should throw not available error', async () => { - expect(() => op.EllipticCurve.add(internal.opTypes.Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( - 'EllipticCurve.add is not available in test context', - ) - expect(() => op.EllipticCurve.mapTo(internal.opTypes.Ec.BN254g2, Bytes(''))).toThrow( - 'EllipticCurve.mapTo is not available in test context', - ) - expect(() => op.EllipticCurve.pairingCheck(internal.opTypes.Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( + 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( 'EllipticCurve.pairingCheck is not available in test context', ) - expect(() => op.EllipticCurve.scalarMul(internal.opTypes.Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( + expect(() => op.EllipticCurve.scalarMul(Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( 'EllipticCurve.scalarMul is not available in test context', ) - expect(() => op.EllipticCurve.scalarMulMulti(internal.opTypes.Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( + expect(() => op.EllipticCurve.scalarMulMulti(Ec.BN254g2, Bytes(''), Bytes(''))).toThrow( 'EllipticCurve.scalarMulMulti is not available in test context', ) - expect(() => op.EllipticCurve.subgroupCheck(internal.opTypes.Ec.BN254g2, Bytes(''))).toThrow( + expect(() => op.EllipticCurve.subgroupCheck(Ec.BN254g2, Bytes(''))).toThrow( 'EllipticCurve.subgroupCheck is not available in test context', ) }) }) }) -const generateEcdsaTestData = (v: internal.opTypes.Ecdsa) => { +const generateEcdsaTestData = (v: Ecdsa) => { const ecdsa = new ec(curveMap[v]) const keyPair = ecdsa.genKeyPair() const pk = keyPair.getPublic('array') diff --git a/tests/pure-op-codes.spec.ts b/tests/pure-op-codes.spec.ts index 0085388..46b66d8 100644 --- a/tests/pure-op-codes.spec.ts +++ b/tests/pure-op-codes.spec.ts @@ -1,5 +1,5 @@ import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { BigUint, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { Base64, BigUint, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' import { @@ -67,7 +67,7 @@ describe('Pure op codes', async () => { base64Encode(Bytes(Array(256).fill(0x00).concat([0xff]))), ])('should decode standard base64 string', async (a) => { const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_base64_decode_standard', asUint8Array(a)))! - const result = op.base64Decode(internal.opTypes.Base64.StdEncoding, a) + const result = op.base64Decode(Base64.StdEncoding, a) expect(result).toEqual(avmResult) }) @@ -77,7 +77,7 @@ describe('Pure op codes', async () => { await expect(getAvmResultRaw({ appClient }, 'verify_base64_decode_standard', asUint8Array(a))).rejects.toThrow( 'illegal base64 data at input byte 0', ) - expect(() => op.base64Decode(internal.opTypes.Base64.StdEncoding, a)).toThrow('illegal base64 data') + expect(() => op.base64Decode(Base64.StdEncoding, a)).toThrow('illegal base64 data') }, ) @@ -90,7 +90,7 @@ describe('Pure op codes', async () => { base64UrlEncode(Bytes(Array(256).fill(0x00).concat([0xff]))), ])('should decode base64url string', async (a) => { const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_base64_decode_url', asUint8Array(a)))! - const result = op.base64Decode(internal.opTypes.Base64.URLEncoding, a) + const result = op.base64Decode(Base64.URLEncoding, a) expect(result).toEqual(avmResult) }) @@ -98,7 +98,7 @@ describe('Pure op codes', async () => { 'should throw error when input is not a valid base64url string', async (a) => { await expect(getAvmResultRaw({ appClient }, 'verify_base64_decode_url', asUint8Array(a))).rejects.toThrow('illegal base64 data') - expect(() => op.base64Decode(internal.opTypes.Base64.URLEncoding, a)).toThrow('illegal base64 data') + expect(() => op.base64Decode(Base64.URLEncoding, a)).toThrow('illegal base64 data') }, ) }) From 3685e8eb6dd810ecec39e9d4d6d783dd56f1ddfd Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 4 Nov 2024 17:58:08 +0800 Subject: [PATCH 47/85] feat: support augmented assignment operators in runtimehelper --- src/runtime-helpers.ts | 43 ++++++++++++++++++- src/test-transformer/node-factory.ts | 10 +++++ .../supported-binary-op-string.ts | 25 ++++++++--- src/test-transformer/visitors.ts | 16 +++++-- 4 files changed, 83 insertions(+), 11 deletions(-) diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 271d844..ed5968a 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -20,7 +20,30 @@ export function switchableValue(x: unknown): bigint | string | boolean { // internalError(`Cannot wrap ${nameOfType(x)}`) // } -type BinaryOps = '+' | '-' | '*' | '**' | '/' | '%' | '>' | '>=' | '<' | '<=' | '===' | '!==' | '<<' | '>>' | '&' | '|' | '^' +type BinaryOps = + | '+' + | '-' + | '*' + | '**' + | '/' + | '%' + | '>' + | '>=' + | '<' + | '<=' + | '===' + | '!==' + | '<<' + | '>>' + | '&' + | '|' + | '^' + | '+=' + | '-=' + | '/=' + | '*=' + | '**=' + | '%=' type UnaryOps = '~' function tryGetBigInt(value: unknown): bigint | undefined { @@ -72,19 +95,25 @@ function uint64BinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps const result = (function () { switch (op) { case '+': + case '+=': return lbi + rbi case '-': + case '-=': return lbi - rbi case '*': + case '*=': return lbi * rbi case '**': + case '**=': if (lbi === 0n && rbi === 0n) { throw internal.errors.codeError('0 ** 0 is undefined') } return lbi ** rbi case '/': + case '/=': return lbi / rbi case '%': + case '%=': return lbi % rbi case '>>': if (rbi > 63n) { @@ -127,19 +156,25 @@ function bigUintBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp const result = (function () { switch (op) { case '+': + case '+=': return lbi + rbi case '-': + case '-=': return lbi - rbi case '*': + case '*=': return lbi * rbi case '**': + case '**=': if (lbi === 0n && rbi === 0n) { throw internal.errors.codeError('0 ** 0 is undefined') } return lbi ** rbi case '/': + case '/=': return lbi / rbi case '%': + case '%=': return lbi % rbi case '>>': throw new internal.errors.CodeError('BigUint does not support >> operator') @@ -207,19 +242,25 @@ function bytesBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps) function defaultBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps): DeliberateAny { switch (op) { case '+': + case '+=': return left + right case '-': + case '-=': return left - right case '*': + case '*=': return left * right case '**': + case '**=': if (left === 0n && right === 0n) { throw new internal.errors.CodeError('0 ** 0 is undefined') } return left ** right case '/': + case '/=': return left / right case '%': + case '%=': return left % right case '>>': if (typeof left === 'bigint' && typeof right === 'bigint') { diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 38dd57d..bff7076 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -28,6 +28,16 @@ export const nodeFactory = { [left, right, factory.createStringLiteral(op)], ) }, + augmentedAssignmentBinaryOp(left: ts.Expression, right: ts.Expression, op: string) { + return factory.createAssignment( + left, + factory.createCallExpression( + factory.createPropertyAccessExpression(factory.createIdentifier('runtimeHelpers'), factory.createIdentifier('binaryOp')), + undefined, + [left, right, factory.createStringLiteral(op)], + ), + ) + }, prefixUnaryOp(operand: ts.Expression, op: string) { return factory.createCallExpression( diff --git a/src/test-transformer/supported-binary-op-string.ts b/src/test-transformer/supported-binary-op-string.ts index 74e67a0..7f51847 100644 --- a/src/test-transformer/supported-binary-op-string.ts +++ b/src/test-transformer/supported-binary-op-string.ts @@ -40,8 +40,6 @@ export function supportedBinaryOpString(x: BinaryOperator): string | undefined { case ts.SyntaxKind.AmpersandAmpersandEqualsToken: case ts.SyntaxKind.AmpersandAmpersandToken: case ts.SyntaxKind.AmpersandEqualsToken: - case ts.SyntaxKind.AsteriskAsteriskEqualsToken: - case ts.SyntaxKind.AsteriskEqualsToken: case ts.SyntaxKind.BarBarEqualsToken: case ts.SyntaxKind.BarBarToken: case ts.SyntaxKind.BarEqualsToken: @@ -52,11 +50,7 @@ export function supportedBinaryOpString(x: BinaryOperator): string | undefined { case ts.SyntaxKind.ExclamationEqualsToken: case ts.SyntaxKind.InKeyword: case ts.SyntaxKind.InstanceOfKeyword: - case ts.SyntaxKind.PercentEqualsToken: - case ts.SyntaxKind.PlusEqualsToken: case ts.SyntaxKind.QuestionQuestionEqualsToken: - case ts.SyntaxKind.MinusEqualsToken: - case ts.SyntaxKind.SlashEqualsToken: case ts.SyntaxKind.QuestionQuestionToken: case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: case ts.SyntaxKind.LessThanLessThanEqualsToken: @@ -66,6 +60,25 @@ export function supportedBinaryOpString(x: BinaryOperator): string | undefined { } } +export function supportedAugmentedAssignmentBinaryOpString(x: BinaryOperator): string | undefined { + switch (x) { + case ts.SyntaxKind.PlusEqualsToken: + return '+=' + case ts.SyntaxKind.MinusEqualsToken: + return '-=' + case ts.SyntaxKind.SlashEqualsToken: + return '/=' + case ts.SyntaxKind.AsteriskEqualsToken: + return '*=' + case ts.SyntaxKind.AsteriskAsteriskEqualsToken: + return '**=' + case ts.SyntaxKind.PercentEqualsToken: + return '%=' + default: + return undefined + } +} + export function supportedPrefixUnaryOpString(x: PrefixUnaryOperator): string | undefined { switch (x) { case ts.SyntaxKind.TildeToken: diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index d3043d6..fdf40e3 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -4,7 +4,11 @@ import type { TypeInfo } from '../encoders' import { DeliberateAny } from '../typescript-helpers' import { TransformerConfig } from './index' import { nodeFactory } from './node-factory' -import { supportedBinaryOpString, supportedPrefixUnaryOpString } from './supported-binary-op-string' +import { + supportedAugmentedAssignmentBinaryOpString, + supportedBinaryOpString, + supportedPrefixUnaryOpString, +} from './supported-binary-op-string' const { factory } = ts @@ -81,9 +85,13 @@ class FunctionOrMethodVisitor { } if (ts.isBinaryExpression(node)) { - const tokenText = supportedBinaryOpString(node.operatorToken.kind) - if (tokenText) { - return nodeFactory.binaryOp(node.left, node.right, tokenText) + const opTokenText = supportedBinaryOpString(node.operatorToken.kind) + if (opTokenText) { + return nodeFactory.binaryOp(node.left, node.right, opTokenText) + } + const augmentedAssignmentOpTokenText = supportedAugmentedAssignmentBinaryOpString(node.operatorToken.kind) + if (augmentedAssignmentOpTokenText) { + return nodeFactory.augmentedAssignmentBinaryOp(node.left, node.right, augmentedAssignmentOpTokenText) } } if (ts.isPrefixUnaryExpression(node)) { From 885a8ceb07b8870375ac05cc5fe2c4e900d0dc37 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 4 Nov 2024 10:58:23 +0800 Subject: [PATCH 48/85] feat: add typescript version of contracts --- tests/artifacts/crypto-ops/contract.algo.ts | 95 + .../data/CryptoOpsContract.approval.teal | 702 +++--- .../data/CryptoOpsContract.arc32.json | 7 +- .../data/CryptoOpsContract.clear.teal | 6 +- .../miscellaneous-ops/contract.algo.ts | 212 ++ .../MiscellaneousOpsContract.approval.teal | 1198 ++++----- .../data/MiscellaneousOpsContract.arc32.json | 1646 ++++++------- .../data/MiscellaneousOpsContract.clear.teal | 6 +- .../artifacts/primitive-ops/contract.algo.ts | 416 ++++ .../data/PrimitiveOpsContract.approval.teal | 2148 +++++++---------- .../data/PrimitiveOpsContract.arc32.json | 154 +- .../data/PrimitiveOpsContract.clear.teal | 6 +- tests/artifacts/state-ops/contract.algo.ts | 151 +- tests/primitives/biguint.spec.ts | 145 ++ tests/pure-op-codes.spec.ts | 11 +- 15 files changed, 3498 insertions(+), 3405 deletions(-) create mode 100644 tests/artifacts/crypto-ops/contract.algo.ts create mode 100644 tests/artifacts/miscellaneous-ops/contract.algo.ts create mode 100644 tests/artifacts/primitive-ops/contract.algo.ts diff --git a/tests/artifacts/crypto-ops/contract.algo.ts b/tests/artifacts/crypto-ops/contract.algo.ts new file mode 100644 index 0000000..e74ae28 --- /dev/null +++ b/tests/artifacts/crypto-ops/contract.algo.ts @@ -0,0 +1,95 @@ +import { arc4, bytes, Ecdsa, ensureBudget, op, OpUpFeeSource, uint64, VrfVerify } from '@algorandfoundation/algorand-typescript' + +export class CryptoOpsContract extends arc4.Contract { + @arc4.abimethod() + public verify_sha256(a: bytes, pad_size: uint64): bytes { + const paddedA = op.bzero(pad_size).concat(a) + const result = op.sha256(paddedA) + return result + } + + @arc4.abimethod() + public verify_sha3_256(a: bytes, pad_size: uint64): bytes { + const paddedA = op.bzero(pad_size).concat(a) + const result = op.sha3_256(paddedA) + return result + } + + @arc4.abimethod() + public verify_keccak_256(a: bytes, pad_size: uint64): bytes { + const paddedA = op.bzero(pad_size).concat(a) + const result = op.keccak256(paddedA) + return result + } + + @arc4.abimethod() + public verify_sha512_256(a: bytes, pad_size: uint64): bytes { + const paddedA = op.bzero(pad_size).concat(a) + const result = op.sha512_256(paddedA) + return result + } + + // TODO: return arc4.Bool to match python version when arc4 types are available + @arc4.abimethod() + public verify_ed25519verify(a: bytes, b: bytes, c: bytes): boolean { + ensureBudget(1900, OpUpFeeSource.GroupCredit) + const result = op.ed25519verify(a, b, c) + return result + } + + // TODO: return arc4.Bool to match python version when arc4 types are available + @arc4.abimethod() + public verify_ed25519verify_bare(a: bytes, b: bytes, c: bytes): boolean { + ensureBudget(1900, OpUpFeeSource.GroupCredit) + const result = op.ed25519verifyBare(a, b, c) + return result + } + + @arc4.abimethod() + public verify_ecdsa_verify_k1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes): boolean { + ensureBudget(3000, OpUpFeeSource.GroupCredit) + const result_k1 = op.ecdsaVerify(Ecdsa.Secp256k1, a, b, c, d, e) + return result_k1 + } + + @arc4.abimethod() + public verify_ecdsa_verify_r1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes): boolean { + ensureBudget(3000, OpUpFeeSource.GroupCredit) + const result_r1 = op.ecdsaVerify(Ecdsa.Secp256r1, a, b, c, d, e) + return result_r1 + } + + @arc4.abimethod() + public verify_ecdsa_recover_k1(a: bytes, b: uint64, c: bytes, d: bytes): readonly [bytes, bytes] { + ensureBudget(3000, OpUpFeeSource.GroupCredit) + return op.ecdsaPkRecover(Ecdsa.Secp256k1, a, b, c, d) + } + + @arc4.abimethod() + public verify_ecdsa_recover_r1(a: bytes, b: uint64, c: bytes, d: bytes): readonly [bytes, bytes] { + /** + * Must fail, AVM does not support Secp256r1 for recover + */ + ensureBudget(3000, OpUpFeeSource.GroupCredit) + return op.ecdsaPkRecover(Ecdsa.Secp256r1, a, b, c, d) + } + + @arc4.abimethod() + public verify_ecdsa_decompress_k1(a: bytes): readonly [bytes, bytes] { + ensureBudget(700, OpUpFeeSource.GroupCredit) + return op.ecdsaPkDecompress(Ecdsa.Secp256k1, a) + } + + @arc4.abimethod() + public verify_ecdsa_decompress_r1(a: bytes): readonly [bytes, bytes] { + ensureBudget(700, OpUpFeeSource.GroupCredit) + return op.ecdsaPkDecompress(Ecdsa.Secp256r1, a) + } + + @arc4.abimethod() + public verify_vrf_verify(a: bytes, b: bytes, c: bytes): readonly [bytes, boolean] { + ensureBudget(5700, OpUpFeeSource.GroupCredit) + const result = op.vrfVerify(VrfVerify.VrfAlgorand, a, b, c) + return result + } +} diff --git a/tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal b/tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal index 748efa2..44fbc8e 100644 --- a/tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal +++ b/tests/artifacts/crypto-ops/data/CryptoOpsContract.approval.teal @@ -1,42 +1,40 @@ #pragma version 10 -tests.artifacts.CryptoOps.contract.CryptoOpsContract.approval_program: - // tests/artifacts/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): +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 main_bare_routing@17 - 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)" + 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 main_verify_sha256_route@2 main_verify_sha3_256_route@3 main_verify_keccak_256_route@4 main_verify_sha512_256_route@5 main_verify_ed25519verify_route@6 main_verify_ed25519verify_bare_route@7 main_verify_ecdsa_verify_k1_route@8 main_verify_ecdsa_verify_r1_route@9 main_verify_ecdsa_recover_k1_route@10 main_verify_ecdsa_recover_r1_route@11 main_verify_ecdsa_decompress_k1_route@12 main_verify_ecdsa_decompress_r1_route@13 main_verify_vrf_verify_route@14 - err // reject transaction + 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 -main_verify_sha256_route@2: - // tests/artifacts/CryptoOps/contract.py:5 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // 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/CryptoOps/contract.py:5 + // tests/artifacts/crypto-ops/contract.algo.ts:4 // @arc4.abimethod() callsub verify_sha256 dup @@ -45,28 +43,28 @@ main_verify_sha256_route@2: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_sha3_256_route@3: - // tests/artifacts/CryptoOps/contract.py:11 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // 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/CryptoOps/contract.py:11 + // tests/artifacts/crypto-ops/contract.algo.ts:11 // @arc4.abimethod() callsub verify_sha3_256 dup @@ -75,28 +73,28 @@ main_verify_sha3_256_route@3: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_keccak_256_route@4: - // tests/artifacts/CryptoOps/contract.py:17 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // 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/CryptoOps/contract.py:17 + // tests/artifacts/crypto-ops/contract.algo.ts:18 // @arc4.abimethod() callsub verify_keccak_256 dup @@ -105,28 +103,28 @@ main_verify_keccak_256_route@4: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_sha512_256_route@5: - // tests/artifacts/CryptoOps/contract.py:23 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // 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/CryptoOps/contract.py:23 + // tests/artifacts/crypto-ops/contract.algo.ts:25 // @arc4.abimethod() callsub verify_sha512_256 dup @@ -135,75 +133,83 @@ main_verify_sha512_256_route@5: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_ed25519verify_route@6: - // tests/artifacts/CryptoOps/contract.py:29 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // 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/CryptoOps/contract.py:29 + // tests/artifacts/crypto-ops/contract.algo.ts:33 // @arc4.abimethod() callsub verify_ed25519verify - byte 0x151f7c75 + bytec_1 // 0x00 + intc_0 // 0 + uncover 2 + setbit + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_ed25519verify_bare_route@7: - // tests/artifacts/CryptoOps/contract.py:35 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // 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/CryptoOps/contract.py:35 + // tests/artifacts/crypto-ops/contract.algo.ts:41 // @arc4.abimethod() callsub verify_ed25519verify_bare - byte 0x151f7c75 + bytec_1 // 0x00 + intc_0 // 0 + uncover 2 + setbit + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_ecdsa_verify_k1_route@8: - // tests/artifacts/CryptoOps/contract.py:41 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // tests/artifacts/crypto-ops/contract.algo.ts:3 + // export class CryptoOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 @@ -214,30 +220,30 @@ main_verify_ecdsa_verify_k1_route@8: extract 2 0 txna ApplicationArgs 5 extract 2 0 - // tests/artifacts/CryptoOps/contract.py:41 + // tests/artifacts/crypto-ops/contract.algo.ts:48 // @arc4.abimethod() callsub verify_ecdsa_verify_k1 - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_0 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_ecdsa_verify_r1_route@9: - // tests/artifacts/CryptoOps/contract.py:47 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // tests/artifacts/crypto-ops/contract.algo.ts:3 + // export class CryptoOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 @@ -248,30 +254,30 @@ main_verify_ecdsa_verify_r1_route@9: extract 2 0 txna ApplicationArgs 5 extract 2 0 - // tests/artifacts/CryptoOps/contract.py:47 + // tests/artifacts/crypto-ops/contract.algo.ts:55 // @arc4.abimethod() callsub verify_ecdsa_verify_r1 - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_0 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_ecdsa_recover_k1_route@10: - // tests/artifacts/CryptoOps/contract.py:53 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // tests/artifacts/crypto-ops/contract.algo.ts:3 + // export class CryptoOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 @@ -280,15 +286,14 @@ main_verify_ecdsa_recover_k1_route@10: extract 2 0 txna ApplicationArgs 4 extract 2 0 - // tests/artifacts/CryptoOps/contract.py:53 + // tests/artifacts/crypto-ops/contract.algo.ts:62 // @arc4.abimethod() callsub verify_ecdsa_recover_k1 - swap - dup + dig 1 len itob extract 6 2 - swap + uncover 2 concat dig 1 len @@ -296,37 +301,36 @@ main_verify_ecdsa_recover_k1_route@10: extract 6 2 uncover 2 concat - swap - dup + dig 1 len - int 4 + intc_2 // 4 + itob extract 6 2 - byte 0x0004 + bytec_2 // 0x0004 swap concat - swap + uncover 2 concat swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_ecdsa_recover_r1_route@11: - // tests/artifacts/CryptoOps/contract.py:60 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // tests/artifacts/crypto-ops/contract.algo.ts:3 + // export class CryptoOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 @@ -335,15 +339,14 @@ main_verify_ecdsa_recover_r1_route@11: extract 2 0 txna ApplicationArgs 4 extract 2 0 - // tests/artifacts/CryptoOps/contract.py:60 + // tests/artifacts/crypto-ops/contract.algo.ts:68 // @arc4.abimethod() callsub verify_ecdsa_recover_r1 - swap - dup + dig 1 len itob extract 6 2 - swap + uncover 2 concat dig 1 len @@ -351,48 +354,46 @@ main_verify_ecdsa_recover_r1_route@11: extract 6 2 uncover 2 concat - swap - dup + dig 1 len - int 4 + intc_2 // 4 + itob extract 6 2 - byte 0x0004 + bytec_2 // 0x0004 swap concat - swap + uncover 2 concat swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_ecdsa_decompress_k1_route@12: - // tests/artifacts/CryptoOps/contract.py:70 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // tests/artifacts/crypto-ops/contract.algo.ts:3 + // export class CryptoOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/CryptoOps/contract.py:70 + // tests/artifacts/crypto-ops/contract.algo.ts:77 // @arc4.abimethod() callsub verify_ecdsa_decompress_k1 - swap - dup + dig 1 len itob extract 6 2 - swap + uncover 2 concat dig 1 len @@ -400,48 +401,46 @@ main_verify_ecdsa_decompress_k1_route@12: extract 6 2 uncover 2 concat - swap - dup + dig 1 len - int 4 + intc_2 // 4 + itob extract 6 2 - byte 0x0004 + bytec_2 // 0x0004 swap concat - swap + uncover 2 concat swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_ecdsa_decompress_r1_route@13: - // tests/artifacts/CryptoOps/contract.py:75 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // tests/artifacts/crypto-ops/contract.algo.ts:3 + // export class CryptoOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/CryptoOps/contract.py:75 + // tests/artifacts/crypto-ops/contract.algo.ts:83 // @arc4.abimethod() callsub verify_ecdsa_decompress_r1 - swap - dup + dig 1 len itob extract 6 2 - swap + uncover 2 concat dig 1 len @@ -449,339 +448,270 @@ main_verify_ecdsa_decompress_r1_route@13: extract 6 2 uncover 2 concat - swap - dup + dig 1 len - int 4 + intc_2 // 4 + itob extract 6 2 - byte 0x0004 + bytec_2 // 0x0004 swap concat - swap + uncover 2 concat swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_vrf_verify_route@14: - // tests/artifacts/CryptoOps/contract.py:80 +__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/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): + // 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/CryptoOps/contract.py:80 + // tests/artifacts/crypto-ops/contract.algo.ts:89 // @arc4.abimethod() callsub verify_vrf_verify - swap - dup + dig 1 len itob extract 6 2 - swap + uncover 2 concat - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_0 // 0 uncover 3 setbit - byte 0x0003 + pushbytes 0x0003 swap concat swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_bare_routing@17: - // tests/artifacts/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): +__puya_arc4_router___bare_routing@17: + // tests/artifacts/crypto-ops/contract.algo.ts:3 + // export class CryptoOpsContract extends arc4.Contract { txn OnCompletion - ! - assert // reject transaction + bnz __puya_arc4_router___after_if_else@21 txn ApplicationID ! assert // is creating - int 1 - return + 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.CryptoOps.contract.CryptoOpsContract.verify_sha256(a: bytes, pad_size: uint64) -> bytes: +// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_sha256(a: bytes, pad_size: uint64) -> bytes: verify_sha256: - // tests/artifacts/CryptoOps/contract.py:5-6 + // tests/artifacts/crypto-ops/contract.algo.ts:4-5 // @arc4.abimethod() - // def verify_sha256(self, a: Bytes, pad_size: UInt64) -> Bytes: + // public verify_sha256(a: bytes, pad_size: uint64): bytes { proto 2 1 - // tests/artifacts/CryptoOps/contract.py:7 - // a = op.bzero(pad_size) + a + // tests/artifacts/crypto-ops/contract.algo.ts:6 + // const paddedA = op.bzero(pad_size).concat(a) frame_dig -1 bzero frame_dig -2 concat - dup - frame_bury -2 - // tests/artifacts/CryptoOps/contract.py:8 - // result = op.sha256(a) + // tests/artifacts/crypto-ops/contract.algo.ts:7 + // const result = op.sha256(paddedA) sha256 - // tests/artifacts/CryptoOps/contract.py:9 + // tests/artifacts/crypto-ops/contract.algo.ts:8 // return result retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_sha3_256(a: bytes, pad_size: uint64) -> bytes: +// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_sha3_256(a: bytes, pad_size: uint64) -> bytes: verify_sha3_256: - // tests/artifacts/CryptoOps/contract.py:11-12 + // tests/artifacts/crypto-ops/contract.algo.ts:11-12 // @arc4.abimethod() - // def verify_sha3_256(self, a: Bytes, pad_size: UInt64) -> Bytes: + // public verify_sha3_256(a: bytes, pad_size: uint64): bytes { proto 2 1 - // tests/artifacts/CryptoOps/contract.py:13 - // a = op.bzero(pad_size) + a + // tests/artifacts/crypto-ops/contract.algo.ts:13 + // const paddedA = op.bzero(pad_size).concat(a) frame_dig -1 bzero frame_dig -2 concat - dup - frame_bury -2 - // tests/artifacts/CryptoOps/contract.py:14 - // result = op.sha3_256(a) + // tests/artifacts/crypto-ops/contract.algo.ts:14 + // const result = op.sha3_256(paddedA) sha3_256 - // tests/artifacts/CryptoOps/contract.py:15 + // tests/artifacts/crypto-ops/contract.algo.ts:15 // return result retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_keccak_256(a: bytes, pad_size: uint64) -> bytes: +// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_keccak_256(a: bytes, pad_size: uint64) -> bytes: verify_keccak_256: - // tests/artifacts/CryptoOps/contract.py:17-18 + // tests/artifacts/crypto-ops/contract.algo.ts:18-19 // @arc4.abimethod() - // def verify_keccak_256(self, a: Bytes, pad_size: UInt64) -> Bytes: + // public verify_keccak_256(a: bytes, pad_size: uint64): bytes { proto 2 1 - // tests/artifacts/CryptoOps/contract.py:19 - // a = op.bzero(pad_size) + a + // tests/artifacts/crypto-ops/contract.algo.ts:20 + // const paddedA = op.bzero(pad_size).concat(a) frame_dig -1 bzero frame_dig -2 concat - dup - frame_bury -2 - // tests/artifacts/CryptoOps/contract.py:20 - // result = op.keccak256(a) + // tests/artifacts/crypto-ops/contract.algo.ts:21 + // const result = op.keccak256(paddedA) keccak256 - // tests/artifacts/CryptoOps/contract.py:21 + // tests/artifacts/crypto-ops/contract.algo.ts:22 // return result retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_sha512_256(a: bytes, pad_size: uint64) -> bytes: +// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_sha512_256(a: bytes, pad_size: uint64) -> bytes: verify_sha512_256: - // tests/artifacts/CryptoOps/contract.py:23-24 + // tests/artifacts/crypto-ops/contract.algo.ts:25-26 // @arc4.abimethod() - // def verify_sha512_256(self, a: Bytes, pad_size: UInt64) -> Bytes: + // public verify_sha512_256(a: bytes, pad_size: uint64): bytes { proto 2 1 - // tests/artifacts/CryptoOps/contract.py:25 - // a = op.bzero(pad_size) + a + // tests/artifacts/crypto-ops/contract.algo.ts:27 + // const paddedA = op.bzero(pad_size).concat(a) frame_dig -1 bzero frame_dig -2 concat - dup - frame_bury -2 - // tests/artifacts/CryptoOps/contract.py:26 - // result = op.sha512_256(a) + // tests/artifacts/crypto-ops/contract.algo.ts:28 + // const result = op.sha512_256(paddedA) sha512_256 - // tests/artifacts/CryptoOps/contract.py:27 + // tests/artifacts/crypto-ops/contract.algo.ts:29 // return result retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ed25519verify(a: bytes, b: bytes, c: bytes) -> bytes: +// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ed25519verify(a: bytes, b: bytes, c: bytes) -> uint64: verify_ed25519verify: - // tests/artifacts/CryptoOps/contract.py:29-30 + // tests/artifacts/crypto-ops/contract.algo.ts:33-34 // @arc4.abimethod() - // def verify_ed25519verify(self, a: Bytes, b: Bytes, c: Bytes) -> arc4.Bool: + // public verify_ed25519verify(a: bytes, b: bytes, c: bytes): boolean { proto 3 1 - // tests/artifacts/CryptoOps/contract.py:31 - // ensure_budget(1900, OpUpFeeSource.GroupCredit) - int 1900 - int 0 + // tests/artifacts/crypto-ops/contract.algo.ts:35 + // ensureBudget(1900, OpUpFeeSource.GroupCredit) + pushint 1900 // 1900 + intc_0 // 0 callsub ensure_budget - // tests/artifacts/CryptoOps/contract.py:32 - // result = op.ed25519verify(a, b, c) + // 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/CryptoOps/contract.py:33 - // return arc4.Bool(result) - byte 0x00 - int 0 - uncover 2 - setbit - retsub - - -// algopy.ensure_budget(required_budget: uint64, fee_source: uint64) -> void: -ensure_budget: - // /algopy.py:11-17 - proto 2 0 - // /algopy.py:18 - frame_dig -2 - int 10 - + - -ensure_budget_while_top@1: - // /algopy.py:19 - frame_dig 0 - global OpcodeBudget - > - bz ensure_budget_after_while@7 - // /algopy.py:20 - itxn_begin - // /algopy.py:21 - int appl - itxn_field TypeEnum - // /algopy.py:22 - int DeleteApplication - itxn_field OnCompletion - // /algopy.py:23 - byte 0x068101 - itxn_field ApprovalProgram - // /algopy.py:24 - byte 0x068101 - itxn_field ClearStateProgram - // /algopy.py:25-29 - 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: - // /algopy.py:27 - int 0 - itxn_field Fee - b ensure_budget_switch_case_next@6 - -ensure_budget_switch_case_1@4: - // /algopy.py:29 - global MinTxnFee - itxn_field Fee - -ensure_budget_switch_case_next@6: - // /algopy.py:30 - itxn_submit - b ensure_budget_while_top@1 - -ensure_budget_after_while@7: + // tests/artifacts/crypto-ops/contract.algo.ts:37 + // return result retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ed25519verify_bare(a: bytes, b: bytes, c: bytes) -> bytes: +// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ed25519verify_bare(a: bytes, b: bytes, c: bytes) -> uint64: verify_ed25519verify_bare: - // tests/artifacts/CryptoOps/contract.py:35-36 + // tests/artifacts/crypto-ops/contract.algo.ts:41-42 // @arc4.abimethod() - // def verify_ed25519verify_bare(self, a: Bytes, b: Bytes, c: Bytes) -> arc4.Bool: + // public verify_ed25519verify_bare(a: bytes, b: bytes, c: bytes): boolean { proto 3 1 - // tests/artifacts/CryptoOps/contract.py:37 - // ensure_budget(1900, OpUpFeeSource.GroupCredit) - int 1900 - int 0 + // tests/artifacts/crypto-ops/contract.algo.ts:43 + // ensureBudget(1900, OpUpFeeSource.GroupCredit) + pushint 1900 // 1900 + intc_0 // 0 callsub ensure_budget - // tests/artifacts/CryptoOps/contract.py:38 - // result = op.ed25519verify_bare(a, b, c) + // 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/CryptoOps/contract.py:39 - // return arc4.Bool(result) - byte 0x00 - int 0 - uncover 2 - setbit + // tests/artifacts/crypto-ops/contract.algo.ts:45 + // return result retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_verify_k1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes) -> uint64: +// 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/CryptoOps/contract.py:41-42 + // tests/artifacts/crypto-ops/contract.algo.ts:48-49 // @arc4.abimethod() - // def verify_ecdsa_verify_k1(self, a: Bytes, b: Bytes, c: Bytes, d: Bytes, e: Bytes) -> bool: + // public verify_ecdsa_verify_k1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes): boolean { proto 5 1 - // tests/artifacts/CryptoOps/contract.py:43 - // ensure_budget(3000, OpUpFeeSource.GroupCredit) - int 3000 - int 0 + // tests/artifacts/crypto-ops/contract.algo.ts:50 + // ensureBudget(3000, OpUpFeeSource.GroupCredit) + intc_3 // 3000 + intc_0 // 0 callsub ensure_budget - // tests/artifacts/CryptoOps/contract.py:44 - // result_k1 = op.ecdsa_verify(op.ECDSA.Secp256k1, a, b, c, d, e) + // 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/CryptoOps/contract.py:45 + // tests/artifacts/crypto-ops/contract.algo.ts:52 // return result_k1 retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_verify_r1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes) -> uint64: +// 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/CryptoOps/contract.py:47-48 + // tests/artifacts/crypto-ops/contract.algo.ts:55-56 // @arc4.abimethod() - // def verify_ecdsa_verify_r1(self, a: Bytes, b: Bytes, c: Bytes, d: Bytes, e: Bytes) -> bool: + // public verify_ecdsa_verify_r1(a: bytes, b: bytes, c: bytes, d: bytes, e: bytes): boolean { proto 5 1 - // tests/artifacts/CryptoOps/contract.py:49 - // ensure_budget(3000, OpUpFeeSource.GroupCredit) - int 3000 - int 0 + // tests/artifacts/crypto-ops/contract.algo.ts:57 + // ensureBudget(3000, OpUpFeeSource.GroupCredit) + intc_3 // 3000 + intc_0 // 0 callsub ensure_budget - // tests/artifacts/CryptoOps/contract.py:50 - // result_r1 = op.ecdsa_verify(op.ECDSA.Secp256r1, a, b, c, d, e) + // 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/CryptoOps/contract.py:51 + // tests/artifacts/crypto-ops/contract.algo.ts:59 // return result_r1 retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_recover_k1(a: bytes, b: uint64, c: bytes, d: bytes) -> bytes, bytes: +// 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/CryptoOps/contract.py:53-56 + // tests/artifacts/crypto-ops/contract.algo.ts:62-63 // @arc4.abimethod() - // def verify_ecdsa_recover_k1( - // self, a: Bytes, b: UInt64, c: Bytes, d: Bytes - // ) -> tuple[Bytes, Bytes]: + // public verify_ecdsa_recover_k1(a: bytes, b: uint64, c: bytes, d: bytes): readonly [bytes, bytes] { proto 4 2 - // tests/artifacts/CryptoOps/contract.py:57 - // ensure_budget(3000, OpUpFeeSource.GroupCredit) - int 3000 - int 0 + // tests/artifacts/crypto-ops/contract.algo.ts:64 + // ensureBudget(3000, OpUpFeeSource.GroupCredit) + intc_3 // 3000 + intc_0 // 0 callsub ensure_budget - // tests/artifacts/CryptoOps/contract.py:58 - // return op.ecdsa_pk_recover(op.ECDSA.Secp256k1, a, b, c, d) + // 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 @@ -790,21 +720,19 @@ verify_ecdsa_recover_k1: retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_recover_r1(a: bytes, b: uint64, c: bytes, d: bytes) -> bytes, bytes: +// 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/CryptoOps/contract.py:60-63 + // tests/artifacts/crypto-ops/contract.algo.ts:68-69 // @arc4.abimethod() - // def verify_ecdsa_recover_r1( - // self, a: Bytes, b: UInt64, c: Bytes, d: Bytes - // ) -> tuple[Bytes, Bytes]: + // public verify_ecdsa_recover_r1(a: bytes, b: uint64, c: bytes, d: bytes): readonly [bytes, bytes] { proto 4 2 - // tests/artifacts/CryptoOps/contract.py:67 - // ensure_budget(3000, OpUpFeeSource.GroupCredit) - int 3000 - int 0 + // tests/artifacts/crypto-ops/contract.algo.ts:73 + // ensureBudget(3000, OpUpFeeSource.GroupCredit) + intc_3 // 3000 + intc_0 // 0 callsub ensure_budget - // tests/artifacts/CryptoOps/contract.py:68 - // return op.ecdsa_pk_recover(op.ECDSA.Secp256r1, a, b, c, d) + // 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 @@ -813,59 +741,101 @@ verify_ecdsa_recover_r1: retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_decompress_k1(a: bytes) -> bytes, bytes: +// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ecdsa_decompress_k1(a: bytes) -> bytes, bytes: verify_ecdsa_decompress_k1: - // tests/artifacts/CryptoOps/contract.py:70-71 + // tests/artifacts/crypto-ops/contract.algo.ts:77-78 // @arc4.abimethod() - // def verify_ecdsa_decompress_k1(self, a: Bytes) -> tuple[Bytes, Bytes]: + // public verify_ecdsa_decompress_k1(a: bytes): readonly [bytes, bytes] { proto 1 2 - // tests/artifacts/CryptoOps/contract.py:72 - // ensure_budget(700, OpUpFeeSource.GroupCredit) - int 700 - int 0 + // tests/artifacts/crypto-ops/contract.algo.ts:79 + // ensureBudget(700, OpUpFeeSource.GroupCredit) + pushint 700 // 700 + intc_0 // 0 callsub ensure_budget - // tests/artifacts/CryptoOps/contract.py:73 - // return op.ecdsa_pk_decompress(op.ECDSA.Secp256k1, a) + // tests/artifacts/crypto-ops/contract.algo.ts:80 + // return op.ecdsaPkDecompress(Ecdsa.Secp256k1, a) frame_dig -1 ecdsa_pk_decompress Secp256k1 retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_ecdsa_decompress_r1(a: bytes) -> bytes, bytes: +// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_ecdsa_decompress_r1(a: bytes) -> bytes, bytes: verify_ecdsa_decompress_r1: - // tests/artifacts/CryptoOps/contract.py:75-76 + // tests/artifacts/crypto-ops/contract.algo.ts:83-84 // @arc4.abimethod() - // def verify_ecdsa_decompress_r1(self, a: Bytes) -> tuple[Bytes, Bytes]: + // public verify_ecdsa_decompress_r1(a: bytes): readonly [bytes, bytes] { proto 1 2 - // tests/artifacts/CryptoOps/contract.py:77 - // ensure_budget(700, OpUpFeeSource.GroupCredit) - int 700 - int 0 + // tests/artifacts/crypto-ops/contract.algo.ts:85 + // ensureBudget(700, OpUpFeeSource.GroupCredit) + pushint 700 // 700 + intc_0 // 0 callsub ensure_budget - // tests/artifacts/CryptoOps/contract.py:78 - // return op.ecdsa_pk_decompress(op.ECDSA.Secp256r1, a) + // tests/artifacts/crypto-ops/contract.algo.ts:86 + // return op.ecdsaPkDecompress(Ecdsa.Secp256r1, a) frame_dig -1 ecdsa_pk_decompress Secp256r1 retsub -// tests.artifacts.CryptoOps.contract.CryptoOpsContract.verify_vrf_verify(a: bytes, b: bytes, c: bytes) -> bytes, uint64: +// tests/artifacts/crypto-ops/contract.algo.ts::CryptoOpsContract.verify_vrf_verify(a: bytes, b: bytes, c: bytes) -> bytes, uint64: verify_vrf_verify: - // tests/artifacts/CryptoOps/contract.py:80-81 + // tests/artifacts/crypto-ops/contract.algo.ts:89-90 // @arc4.abimethod() - // def verify_vrf_verify(self, a: Bytes, b: Bytes, c: Bytes) -> tuple[Bytes, bool]: + // public verify_vrf_verify(a: bytes, b: bytes, c: bytes): readonly [bytes, boolean] { proto 3 2 - // tests/artifacts/CryptoOps/contract.py:82 - // ensure_budget(5700, OpUpFeeSource.GroupCredit) - int 5700 - int 0 + // tests/artifacts/crypto-ops/contract.algo.ts:91 + // ensureBudget(5700, OpUpFeeSource.GroupCredit) + pushint 5700 // 5700 + intc_0 // 0 callsub ensure_budget - // tests/artifacts/CryptoOps/contract.py:83 - // result = op.vrf_verify(op.VrfVerify.VrfAlgorand, a, b, c) + // 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/CryptoOps/contract.py:84 + // 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 index 007f9f8..e60b9a5 100644 --- a/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc32.json +++ b/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc32.json @@ -67,8 +67,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuQ3J5cHRvT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdAMTcKICAgIG1ldGhvZCAidmVyaWZ5X3NoYTI1NihieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X3NoYTNfMjU2KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfa2VjY2FrXzI1NihieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X3NoYTUxMl8yNTYoYnl0ZVtdLHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9lZDI1NTE5dmVyaWZ5KGJ5dGVbXSxieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmUoYnl0ZVtdLGJ5dGVbXSxieXRlW10pYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2VjZHNhX3ZlcmlmeV9rMShieXRlW10sYnl0ZVtdLGJ5dGVbXSxieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9lY2RzYV92ZXJpZnlfcjEoYnl0ZVtdLGJ5dGVbXSxieXRlW10sYnl0ZVtdLGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMShieXRlW10sdWludDY0LGJ5dGVbXSxieXRlW10pKGJ5dGVbXSxieXRlW10pIgogICAgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMShieXRlW10sdWludDY0LGJ5dGVbXSxieXRlW10pKGJ5dGVbXSxieXRlW10pIgogICAgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMShieXRlW10pKGJ5dGVbXSxieXRlW10pIgogICAgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMShieXRlW10pKGJ5dGVbXSxieXRlW10pIgogICAgbWV0aG9kICJ2ZXJpZnlfdnJmX3ZlcmlmeShieXRlW10sYnl0ZVtdLGJ5dGVbXSkoYnl0ZVtdLGJvb2wpIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl92ZXJpZnlfc2hhMjU2X3JvdXRlQDIgbWFpbl92ZXJpZnlfc2hhM18yNTZfcm91dGVAMyBtYWluX3ZlcmlmeV9rZWNjYWtfMjU2X3JvdXRlQDQgbWFpbl92ZXJpZnlfc2hhNTEyXzI1Nl9yb3V0ZUA1IG1haW5fdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfcm91dGVANiBtYWluX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmVfcm91dGVANyBtYWluX3ZlcmlmeV9lY2RzYV92ZXJpZnlfazFfcm91dGVAOCBtYWluX3ZlcmlmeV9lY2RzYV92ZXJpZnlfcjFfcm91dGVAOSBtYWluX3ZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxX3JvdXRlQDEwIG1haW5fdmVyaWZ5X2VjZHNhX3JlY292ZXJfcjFfcm91dGVAMTEgbWFpbl92ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMV9yb3V0ZUAxMiBtYWluX3ZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX3IxX3JvdXRlQDEzIG1haW5fdmVyaWZ5X3ZyZl92ZXJpZnlfcm91dGVAMTQKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X3NoYTI1Nl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NoYTI1NgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3NoYTNfMjU2X3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGEzXzI1NgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2tlY2Nha18yNTZfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2tlY2Nha18yNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zaGE1MTJfMjU2X3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGE1MTJfMjU2CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZWQyNTUxOXZlcmlmeV9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lZDI1NTE5dmVyaWZ5CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmVfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWQyNTUxOXZlcmlmeV9iYXJlCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9lY2RzYV92ZXJpZnlfazFfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV92ZXJpZnlfazEKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9lY2RzYV92ZXJpZnlfcjFfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV92ZXJpZnlfcjEKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaW50IDQKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBieXRlIDB4MDAwNAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMQogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGludCA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZSAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazFfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBDcnlwdG9PcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX2sxCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaW50IDQKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBieXRlIDB4MDAwNAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMV9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjEKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBpbnQgNAogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGJ5dGUgMHgwMDA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV92cmZfdmVyaWZ5X3JvdXRlQDE0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6ODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV92cmZfdmVyaWZ5CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgwMDAzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfc2hhMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTI1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NS02CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9zaGEyNTYoc2VsZiwgYTogQnl0ZXMsIHBhZF9zaXplOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjcKICAgIC8vIGEgPSBvcC5iemVybyhwYWRfc2l6ZSkgKyBhCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgZHVwCiAgICBmcmFtZV9idXJ5IC0yCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjgKICAgIC8vIHJlc3VsdCA9IG9wLnNoYTI1NihhKQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5DcnlwdG9PcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X3NoYTNfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTNfMjU2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToxMS0xMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2hhM18yNTYoc2VsZiwgYTogQnl0ZXMsIHBhZF9zaXplOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjEzCiAgICAvLyBhID0gb3AuYnplcm8ocGFkX3NpemUpICsgYQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIGR1cAogICAgZnJhbWVfYnVyeSAtMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToxNAogICAgLy8gcmVzdWx0ID0gb3Auc2hhM18yNTYoYSkKICAgIHNoYTNfMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjE1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuQ3J5cHRvT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9rZWNjYWtfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2tlY2Nha18yNTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjE3LTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9rZWNjYWtfMjU2KHNlbGYsIGE6IEJ5dGVzLCBwYWRfc2l6ZTogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToxOQogICAgLy8gYSA9IG9wLmJ6ZXJvKHBhZF9zaXplKSArIGEKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgLTIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MjAKICAgIC8vIHJlc3VsdCA9IG9wLmtlY2NhazI1NihhKQogICAga2VjY2FrMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjIxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuQ3J5cHRvT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9zaGE1MTJfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTUxMl8yNTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjIzLTI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9zaGE1MTJfMjU2KHNlbGYsIGE6IEJ5dGVzLCBwYWRfc2l6ZTogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToyNQogICAgLy8gYSA9IG9wLmJ6ZXJvKHBhZF9zaXplKSArIGEKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgLTIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MjYKICAgIC8vIHJlc3VsdCA9IG9wLnNoYTUxMl8yNTYoYSkKICAgIHNoYTUxMl8yNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MjcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5DcnlwdG9PcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VkMjU1MTl2ZXJpZnkoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9lZDI1NTE5dmVyaWZ5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weToyOS0zMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZWQyNTUxOXZlcmlmeShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMsIGM6IEJ5dGVzKSAtPiBhcmM0LkJvb2w6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MzEKICAgIC8vIGVuc3VyZV9idWRnZXQoMTkwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludCAxOTAwCiAgICBpbnQgMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjMyCiAgICAvLyByZXN1bHQgPSBvcC5lZDI1NTE5dmVyaWZ5KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlZDI1NTE5dmVyaWZ5CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjMzCiAgICAvLyByZXR1cm4gYXJjNC5Cb29sKHJlc3VsdCkKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICByZXRzdWIKCgovLyBhbGdvcHkuZW5zdXJlX2J1ZGdldChyZXF1aXJlZF9idWRnZXQ6IHVpbnQ2NCwgZmVlX3NvdXJjZTogdWludDY0KSAtPiB2b2lkOgplbnN1cmVfYnVkZ2V0OgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjExLTE3CiAgICBwcm90byAyIDAKICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToxOAogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMTAKICAgICsKCmVuc3VyZV9idWRnZXRfd2hpbGVfdG9wQDE6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MTkKICAgIGZyYW1lX2RpZyAwCiAgICBnbG9iYWwgT3Bjb2RlQnVkZ2V0CiAgICA+CiAgICBieiBlbnN1cmVfYnVkZ2V0X2FmdGVyX3doaWxlQDcKICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToyMAogICAgaXR4bl9iZWdpbgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjIxCiAgICBpbnQgYXBwbAogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjIyCiAgICBpbnQgRGVsZXRlQXBwbGljYXRpb24KICAgIGl0eG5fZmllbGQgT25Db21wbGV0aW9uCiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjMKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQXBwcm92YWxQcm9ncmFtCiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MjQKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIDxhbGdvcHk+L2FsZ29weS5weToyNS0yOQogICAgZnJhbWVfZGlnIC0xCiAgICBzd2l0Y2ggZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8wQDMgZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8xQDQKICAgIGIgZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDYKCmVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMEAzOgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjI3CiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIGIgZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDYKCmVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMUA0OgogICAgLy8gPGFsZ29weT4vYWxnb3B5LnB5OjI5CiAgICBnbG9iYWwgTWluVHhuRmVlCiAgICBpdHhuX2ZpZWxkIEZlZQoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDY6CiAgICAvLyA8YWxnb3B5Pi9hbGdvcHkucHk6MzAKICAgIGl0eG5fc3VibWl0CiAgICBiIGVuc3VyZV9idWRnZXRfd2hpbGVfdG9wQDEKCmVuc3VyZV9idWRnZXRfYWZ0ZXJfd2hpbGVANzoKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5DcnlwdG9PcHMuY29udHJhY3QuQ3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MzUtMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMsIGM6IEJ5dGVzKSAtPiBhcmM0LkJvb2w6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6MzcKICAgIC8vIGVuc3VyZV9idWRnZXQoMTkwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludCAxOTAwCiAgICBpbnQgMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjM4CiAgICAvLyByZXN1bHQgPSBvcC5lZDI1NTE5dmVyaWZ5X2JhcmUoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGVkMjU1MTl2ZXJpZnlfYmFyZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTozOQogICAgLy8gcmV0dXJuIGFyYzQuQm9vbChyZXN1bHQpCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMsIGQ6IGJ5dGVzLCBlOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0MS00MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgYzogQnl0ZXMsIGQ6IEJ5dGVzLCBlOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDUgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0MwogICAgLy8gZW5zdXJlX2J1ZGdldCgzMDAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDMwMDAKICAgIGludCAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NDQKICAgIC8vIHJlc3VsdF9rMSA9IG9wLmVjZHNhX3ZlcmlmeShvcC5FQ0RTQS5TZWNwMjU2azEsIGEsIGIsIGMsIGQsIGUpCiAgICBmcmFtZV9kaWcgLTUKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWNkc2FfdmVyaWZ5IFNlY3AyNTZrMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0NQogICAgLy8gcmV0dXJuIHJlc3VsdF9rMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMsIGQ6IGJ5dGVzLCBlOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0Ny00OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgYzogQnl0ZXMsIGQ6IEJ5dGVzLCBlOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDUgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo0OQogICAgLy8gZW5zdXJlX2J1ZGdldCgzMDAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDMwMDAKICAgIGludCAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NTAKICAgIC8vIHJlc3VsdF9yMSA9IG9wLmVjZHNhX3ZlcmlmeShvcC5FQ0RTQS5TZWNwMjU2cjEsIGEsIGIsIGMsIGQsIGUpCiAgICBmcmFtZV9kaWcgLTUKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWNkc2FfdmVyaWZ5IFNlY3AyNTZyMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo1MQogICAgLy8gcmV0dXJuIHJlc3VsdF9yMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMShhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzLCBieXRlczoKdmVyaWZ5X2VjZHNhX3JlY292ZXJfazE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjUzLTU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxKAogICAgLy8gICAgIHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQsIGM6IEJ5dGVzLCBkOiBCeXRlcwogICAgLy8gKSAtPiB0dXBsZVtCeXRlcywgQnl0ZXNdOgogICAgcHJvdG8gNCAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjU3CiAgICAvLyBlbnN1cmVfYnVkZ2V0KDMwMDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgMzAwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo1OAogICAgLy8gcmV0dXJuIG9wLmVjZHNhX3BrX3JlY292ZXIob3AuRUNEU0EuU2VjcDI1NmsxLCBhLCBiLCBjLCBkKQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19yZWNvdmVyIFNlY3AyNTZrMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMShhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMpIC0+IGJ5dGVzLCBieXRlczoKdmVyaWZ5X2VjZHNhX3JlY292ZXJfcjE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjYwLTYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxKAogICAgLy8gICAgIHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQsIGM6IEJ5dGVzLCBkOiBCeXRlcwogICAgLy8gKSAtPiB0dXBsZVtCeXRlcywgQnl0ZXNdOgogICAgcHJvdG8gNCAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjY3CiAgICAvLyBlbnN1cmVfYnVkZ2V0KDMwMDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgMzAwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo2OAogICAgLy8gcmV0dXJuIG9wLmVjZHNhX3BrX3JlY292ZXIob3AuRUNEU0EuU2VjcDI1NnIxLCBhLCBiLCBjLCBkKQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19yZWNvdmVyIFNlY3AyNTZyMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzAtNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazEoc2VsZiwgYTogQnl0ZXMpIC0+IHR1cGxlW0J5dGVzLCBCeXRlc106CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzIKICAgIC8vIGVuc3VyZV9idWRnZXQoNzAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDcwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo3MwogICAgLy8gcmV0dXJuIG9wLmVjZHNhX3BrX2RlY29tcHJlc3Mob3AuRUNEU0EuU2VjcDI1NmsxLCBhKQogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19kZWNvbXByZXNzIFNlY3AyNTZrMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzUtNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjEoc2VsZiwgYTogQnl0ZXMpIC0+IHR1cGxlW0J5dGVzLCBCeXRlc106CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6NzcKICAgIC8vIGVuc3VyZV9idWRnZXQoNzAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50IDcwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo3OAogICAgLy8gcmV0dXJuIG9wLmVjZHNhX3BrX2RlY29tcHJlc3Mob3AuRUNEU0EuU2VjcDI1NnIxLCBhKQogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19kZWNvbXByZXNzIFNlY3AyNTZyMQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLkNyeXB0b09wcy5jb250cmFjdC5DcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfdnJmX3ZlcmlmeShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlcywgdWludDY0Ogp2ZXJpZnlfdnJmX3ZlcmlmeToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9DcnlwdG9PcHMvY29udHJhY3QucHk6ODAtODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3ZyZl92ZXJpZnkoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzLCBjOiBCeXRlcykgLT4gdHVwbGVbQnl0ZXMsIGJvb2xdOgogICAgcHJvdG8gMyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjgyCiAgICAvLyBlbnN1cmVfYnVkZ2V0KDU3MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgNTcwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL0NyeXB0b09wcy9jb250cmFjdC5weTo4MwogICAgLy8gcmVzdWx0ID0gb3AudnJmX3ZlcmlmeShvcC5WcmZWZXJpZnkuVnJmQWxnb3JhbmQsIGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICB2cmZfdmVyaWZ5IFZyZkFsZ29yYW5kCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5Ojg0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuQ3J5cHRvT3BzLmNvbnRyYWN0LkNyeXB0b09wc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvQ3J5cHRvT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIENyeXB0b09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMCAxIDQgMzAwMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1IDB4MDAgMHgwMDA0IDB4MDY4MTAxCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE3CiAgICBwdXNoYnl0ZXNzIDB4MzQ1NmM0YzMgMHhlODQ0MmI4NCAweDY1ZjU2N2FhIDB4MjU4NDU1YjEgMHgzNWFmMGYzOCAweDY1ODJjOTk3IDB4NjI5OGZmYmIgMHgzODg1YjU0ZiAweDIxNjRlMGJmIDB4NzU1Yjc5YTUgMHhmMDZiYjA3NyAweDEzM2Y4Y2NjIDB4MmY3YzY4YTkgLy8gbWV0aG9kICJ2ZXJpZnlfc2hhMjU2KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2hhM18yNTYoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9rZWNjYWtfMjU2KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2hhNTEyXzI1NihieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2VkMjU1MTl2ZXJpZnkoYnl0ZVtdLGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZShieXRlW10sYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGJ5dGVbXSxieXRlW10sYnl0ZVtdLGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMShieXRlW10sYnl0ZVtdLGJ5dGVbXSxieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxKGJ5dGVbXSx1aW50NjQsYnl0ZVtdLGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxKGJ5dGVbXSx1aW50NjQsYnl0ZVtdLGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX2sxKGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV9lY2RzYV9kZWNvbXByZXNzX3IxKGJ5dGVbXSkoYnl0ZVtdLGJ5dGVbXSkiLCBtZXRob2QgInZlcmlmeV92cmZfdmVyaWZ5KGJ5dGVbXSxieXRlW10sYnl0ZVtdKShieXRlW10sYm9vbCkiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hhMjU2X3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NoYTNfMjU2X3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2tlY2Nha18yNTZfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hhNTEyXzI1Nl9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lY2RzYV92ZXJpZnlfazFfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZWNkc2FfdmVyaWZ5X3IxX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX3JlY292ZXJfazFfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX3JlY292ZXJfcjFfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazFfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjFfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3ZyZl92ZXJpZnlfcm91dGVAMTQKICAgIGludGNfMCAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaGEyNTZfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2hhMjU2CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NoYTNfMjU2X3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2hhM18yNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfa2VjY2FrXzI1Nl9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoxOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoxOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2tlY2Nha18yNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hhNTEyXzI1Nl9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NoYTUxMl8yNTYKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZWQyNTUxOXZlcmlmeV9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWQyNTUxOXZlcmlmeQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmVfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzAgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lY2RzYV92ZXJpZnlfazFfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDUKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMCAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMV9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9lY2RzYV92ZXJpZnlfcjEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBDcnlwdG9PcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2VjZHNhX3JlY292ZXJfazEKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNAogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGJ5dGVjXzIgLy8gMHgwMDA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIENyeXB0b09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMQogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGludGNfMiAvLyA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZWNfMiAvLyAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazFfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMQogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGludGNfMiAvLyA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZWNfMiAvLyAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjFfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMQogICAgZGlnIDEKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGRpZyAxCiAgICBsZW4KICAgIGludGNfMiAvLyA0CiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgYnl0ZWNfMiAvLyAweDAwMDQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3ZyZl92ZXJpZnlfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV92cmZfdmVyaWZ5CiAgICBkaWcgMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMwogICAgc2V0Yml0CiAgICBwdXNoYnl0ZXMgMHgwMDAzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIxCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgQ3J5cHRvT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMCAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfc2hhMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTI1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NC01CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zaGEyNTYoYTogYnl0ZXMsIHBhZF9zaXplOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NgogICAgLy8gY29uc3QgcGFkZGVkQSA9IG9wLmJ6ZXJvKHBhZF9zaXplKS5jb25jYXQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjcKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNoYTI1NihwYWRkZWRBKQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjgKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6OkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9zaGEzXzI1NihhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zaGEzXzI1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEtMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NoYTNfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNoYTNfMjU2KHBhZGRlZEEpCiAgICBzaGEzXzI1NgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoxNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2tlY2Nha18yNTYoYTogYnl0ZXMsIHBhZF9zaXplOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfa2VjY2FrXzI1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgtMTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2tlY2Nha18yNTYoYTogYnl0ZXMsIHBhZF9zaXplOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Aua2VjY2FrMjU2KHBhZGRlZEEpCiAgICBrZWNjYWsyNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6OkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9zaGE1MTJfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NoYTUxMl8yNTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1LTI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zaGE1MTJfMjU2KGE6IGJ5dGVzLCBwYWRfc2l6ZTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3CiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNoYTUxMl8yNTYocGFkZGVkQSkKICAgIHNoYTUxMl8yNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6OkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9lZDI1NTE5dmVyaWZ5KGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2VkMjU1MTl2ZXJpZnk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzLTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9lZDI1NTE5dmVyaWZ5KGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gZW5zdXJlQnVkZ2V0KDE5MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBwdXNoaW50IDE5MDAgLy8gMTkwMAogICAgaW50Y18wIC8vIDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozNgogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZWQyNTUxOXZlcmlmeShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWQyNTUxOXZlcmlmeQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VkMjU1MTl2ZXJpZnlfYmFyZShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxLTQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9lZDI1NTE5dmVyaWZ5X2JhcmUoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzCiAgICAvLyBlbnN1cmVCdWRnZXQoMTkwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIHB1c2hpbnQgMTkwMCAvLyAxOTAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5lZDI1NTE5dmVyaWZ5QmFyZShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWQyNTUxOXZlcmlmeV9iYXJlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMsIGQ6IGJ5dGVzLCBlOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo0OC00OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZWNkc2FfdmVyaWZ5X2sxKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMsIGQ6IGJ5dGVzLCBlOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gNSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBlbnN1cmVCdWRnZXQoMzAwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludGNfMyAvLyAzMDAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyBjb25zdCByZXN1bHRfazEgPSBvcC5lY2RzYVZlcmlmeShFY2RzYS5TZWNwMjU2azEsIGEsIGIsIGMsIGQsIGUpCiAgICBmcmFtZV9kaWcgLTUKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZWNkc2FfdmVyaWZ5IFNlY3AyNTZrMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1MgogICAgLy8gcmV0dXJuIHJlc3VsdF9rMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiBieXRlcywgZTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NTUtNTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX3ZlcmlmeV9yMShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiBieXRlcywgZTogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDUgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1NwogICAgLy8gZW5zdXJlQnVkZ2V0KDMwMDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnRjXzMgLy8gMzAwMAogICAgaW50Y18wIC8vIDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo1OAogICAgLy8gY29uc3QgcmVzdWx0X3IxID0gb3AuZWNkc2FWZXJpZnkoRWNkc2EuU2VjcDI1NnIxLCBhLCBiLCBjLCBkLCBlKQogICAgZnJhbWVfZGlnIC01CiAgICBmcmFtZV9kaWcgLTQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3ZlcmlmeSBTZWNwMjU2cjEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkKICAgIC8vIHJldHVybiByZXN1bHRfcjEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6OkNyeXB0b09wc0NvbnRyYWN0LnZlcmlmeV9lY2RzYV9yZWNvdmVyX2sxKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IGJ5dGVzLCBkOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9rMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NjItNjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX3JlY292ZXJfazEoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMsIGQ6IGJ5dGVzKTogcmVhZG9ubHkgW2J5dGVzLCBieXRlc10gewogICAgcHJvdG8gNCAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjY0CiAgICAvLyBlbnN1cmVCdWRnZXQoMzAwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludGNfMyAvLyAzMDAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjY1CiAgICAvLyByZXR1cm4gb3AuZWNkc2FQa1JlY292ZXIoRWNkc2EuU2VjcDI1NmsxLCBhLCBiLCBjLCBkKQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBlY2RzYV9wa19yZWNvdmVyIFNlY3AyNTZrMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo6Q3J5cHRvT3BzQ29udHJhY3QudmVyaWZ5X2VjZHNhX3JlY292ZXJfcjEoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMsIGQ6IGJ5dGVzKSAtPiBieXRlcywgYnl0ZXM6CnZlcmlmeV9lY2RzYV9yZWNvdmVyX3IxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo2OC02OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZWNkc2FfcmVjb3Zlcl9yMShhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJ5dGVzXSB7CiAgICBwcm90byA0IDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGVuc3VyZUJ1ZGdldCgzMDAwLCBPcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgaW50Y18zIC8vIDMwMDAKICAgIGludGNfMCAvLyAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIHJldHVybiBvcC5lY2RzYVBrUmVjb3ZlcihFY2RzYS5TZWNwMjU2cjEsIGEsIGIsIGMsIGQpCiAgICBmcmFtZV9kaWcgLTQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3BrX3JlY292ZXIgU2VjcDI1NnIxCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19rMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzctNzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfazEoYTogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJ5dGVzXSB7CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6NzkKICAgIC8vIGVuc3VyZUJ1ZGdldCg3MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBwdXNoaW50IDcwMCAvLyA3MDAKICAgIGludGNfMCAvLyAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODAKICAgIC8vIHJldHVybiBvcC5lY2RzYVBrRGVjb21wcmVzcyhFY2RzYS5TZWNwMjU2azEsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3BrX2RlY29tcHJlc3MgU2VjcDI1NmsxCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMShhOiBieXRlcykgLT4gYnl0ZXMsIGJ5dGVzOgp2ZXJpZnlfZWNkc2FfZGVjb21wcmVzc19yMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODMtODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2VjZHNhX2RlY29tcHJlc3NfcjEoYTogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJ5dGVzXSB7CiAgICBwcm90byAxIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIGVuc3VyZUJ1ZGdldCg3MDAsIE9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBwdXNoaW50IDcwMCAvLyA3MDAKICAgIGludGNfMCAvLyAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODYKICAgIC8vIHJldHVybiBvcC5lY2RzYVBrRGVjb21wcmVzcyhFY2RzYS5TZWNwMjU2cjEsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGVjZHNhX3BrX2RlY29tcHJlc3MgU2VjcDI1NnIxCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC52ZXJpZnlfdnJmX3ZlcmlmeShhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiBieXRlcywgdWludDY0Ogp2ZXJpZnlfdnJmX3ZlcmlmeToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9jcnlwdG8tb3BzL2NvbnRyYWN0LmFsZ28udHM6ODktOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3ZyZl92ZXJpZnkoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiBieXRlcyk6IHJlYWRvbmx5IFtieXRlcywgYm9vbGVhbl0gewogICAgcHJvdG8gMyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyBlbnN1cmVCdWRnZXQoNTcwMCwgT3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIHB1c2hpbnQgNTcwMCAvLyA1NzAwCiAgICBpbnRjXzAgLy8gMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjkyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC52cmZWZXJpZnkoVnJmVmVyaWZ5LlZyZkFsZ29yYW5kLCBhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgdnJmX3ZlcmlmeSBWcmZBbGdvcmFuZAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2NyeXB0by1vcHMvY29udHJhY3QuYWxnby50czo5MwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gX3B1eWFfbGliLnV0aWwuZW5zdXJlX2J1ZGdldChyZXF1aXJlZF9idWRnZXQ6IHVpbnQ2NCwgZmVlX3NvdXJjZTogdWludDY0KSAtPiB2b2lkOgplbnN1cmVfYnVkZ2V0OgogICAgcHJvdG8gMiAwCiAgICBmcmFtZV9kaWcgLTIKICAgIHB1c2hpbnQgMTAgLy8gMTAKICAgICsKCmVuc3VyZV9idWRnZXRfd2hpbGVfdG9wQDE6CiAgICBmcmFtZV9kaWcgMAogICAgZ2xvYmFsIE9wY29kZUJ1ZGdldAogICAgPgogICAgYnogZW5zdXJlX2J1ZGdldF9hZnRlcl93aGlsZUA3CiAgICBpdHhuX2JlZ2luCiAgICBwdXNoaW50IDYgLy8gYXBwbAogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgcHVzaGludCA1IC8vIERlbGV0ZUFwcGxpY2F0aW9uCiAgICBpdHhuX2ZpZWxkIE9uQ29tcGxldGlvbgogICAgYnl0ZWNfMyAvLyAweDA2ODEwMQogICAgaXR4bl9maWVsZCBBcHByb3ZhbFByb2dyYW0KICAgIGJ5dGVjXzMgLy8gMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KICAgIGZyYW1lX2RpZyAtMQogICAgc3dpdGNoIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMEAzIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMUA0CiAgICBiIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfbmV4dEA2CgplbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzBAMzoKICAgIGludGNfMCAvLyAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgYiBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANgoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8xQDQ6CiAgICBnbG9iYWwgTWluVHhuRmVlCiAgICBpdHhuX2ZpZWxkIEZlZQoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDY6CiAgICBpdHhuX3N1Ym1pdAogICAgYiBlbnN1cmVfYnVkZ2V0X3doaWxlX3RvcEAxCgplbnN1cmVfYnVkZ2V0X2FmdGVyX3doaWxlQDc6CiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvY3J5cHRvLW9wcy9jb250cmFjdC5hbGdvLnRzOjpDcnlwdG9PcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" }, "state": { "global": { @@ -309,8 +309,7 @@ "readonly": false, "returns": { "type": "(byte[],byte[])" - }, - "desc": "Must fail, AVM does not support Secp256r1 for recover" + } }, { "name": "verify_ecdsa_decompress_k1", diff --git a/tests/artifacts/crypto-ops/data/CryptoOpsContract.clear.teal b/tests/artifacts/crypto-ops/data/CryptoOpsContract.clear.teal index e1705b2..6ee7565 100644 --- a/tests/artifacts/crypto-ops/data/CryptoOpsContract.clear.teal +++ b/tests/artifacts/crypto-ops/data/CryptoOpsContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.CryptoOps.contract.CryptoOpsContract.clear_state_program: - // tests/artifacts/CryptoOps/contract.py:4 - // class CryptoOpsContract(ARC4Contract): - int 1 +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 new file mode 100644 index 0000000..0caefed --- /dev/null +++ b/tests/artifacts/miscellaneous-ops/contract.algo.ts @@ -0,0 +1,212 @@ +import { arc4, Base64, BigUint, Bytes, bytes, err, op, uint64 } from '@algorandfoundation/algorand-typescript' + +export class MiscellaneousOpsContract extends arc4.Contract { + @arc4.abimethod() + public verify_addw(a: uint64, b: uint64): readonly [uint64, uint64] { + const result = op.addw(a, b) + return result + } + + @arc4.abimethod() + public verify_base64_decode_standard(a: bytes): bytes { + const result = op.base64Decode(Base64.StdEncoding, a) + return result + } + + @arc4.abimethod() + public verify_base64_decode_url(a: bytes): bytes { + const result = op.base64Decode(Base64.URLEncoding, a) + return result + } + + @arc4.abimethod() + public verify_bytes_bitlen(a: bytes, pad_a_size: uint64): uint64 { + const paddedA = op.bzero(pad_a_size).concat(a) + const result = op.bitLength(paddedA) + return result + } + + @arc4.abimethod() + public verify_uint64_bitlen(a: uint64): uint64 { + const result = op.bitLength(a) + return result + } + + @arc4.abimethod() + public verify_bsqrt(a: bytes): bytes { + const a_biguint = BigUint(a) + const result = op.bsqrt(a_biguint) + return Bytes(result) + } + + @arc4.abimethod() + public verify_btoi(a: bytes): uint64 { + const result = op.btoi(a) + return result + } + + @arc4.abimethod() + public verify_bzero(a: uint64): bytes { + const result = op.bzero(a) + return op.sha256(result) + } + + @arc4.abimethod() + public verify_concat(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64): bytes { + const paddedA = op.bzero(pad_a_size).concat(a) + const paddedB = op.bzero(pad_b_size).concat(b) + const result = paddedA.concat(paddedB) + const resultHash = op.sha256(result) + return resultHash + } + + @arc4.abimethod() + public verify_divmodw(a: uint64, b: uint64, c: uint64, d: uint64): readonly [uint64, uint64, uint64, uint64] { + const result = op.divmodw(a, b, c, d) + return result + } + + @arc4.abimethod() + public verify_divw(a: uint64, b: uint64, c: uint64): uint64 { + const result = op.divw(a, b, c) + return result + } + + @arc4.abimethod() + public verify_err(): void { + err() + } + + @arc4.abimethod() + public verify_exp(a: uint64, b: uint64): uint64 { + const result = op.exp(a, b) + return result + } + + @arc4.abimethod() + public verify_expw(a: uint64, b: uint64): readonly [uint64, uint64] { + const result = op.expw(a, b) + return result + } + + @arc4.abimethod() + public verify_extract(a: bytes, b: uint64, c: uint64): bytes { + const result = op.extract(a, b, c) + 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) + return result + } + + @arc4.abimethod() + public verify_extract_uint16(a: bytes, b: uint64): uint64 { + const result = op.extractUint16(a, b) + return result + } + + @arc4.abimethod() + public verify_extract_uint32(a: bytes, b: uint64): uint64 { + const result = op.extractUint32(a, b) + return result + } + + @arc4.abimethod() + public verify_extract_uint64(a: bytes, b: uint64): uint64 { + const result = op.extractUint64(a, b) + return result + } + + @arc4.abimethod() + public verify_getbit_bytes(a: bytes, b: uint64): uint64 { + const result = op.getBit(a, b) + return result + } + + @arc4.abimethod() + public verify_getbit_uint64(a: uint64, b: uint64): uint64 { + const result = op.getBit(a, b) + return result + } + + @arc4.abimethod() + public verify_getbyte(a: bytes, b: uint64): uint64 { + const result = op.getByte(a, b) + return result + } + + @arc4.abimethod() + public verify_itob(a: uint64): bytes { + const result = op.itob(a) + return result + } + + @arc4.abimethod() + public verify_mulw(a: uint64, b: uint64): readonly [uint64, uint64] { + const result = op.mulw(a, b) + return result + } + + @arc4.abimethod() + public verify_replace(a: bytes, b: uint64, c: bytes): bytes { + const result = op.replace(a, b, c) + return result + } + + @arc4.abimethod() + public verify_select_bytes(a: bytes, b: bytes, c: uint64): bytes { + const result = op.select(a, b, c) + return result + } + + @arc4.abimethod() + public verify_select_uint64(a: uint64, b: uint64, c: uint64): uint64 { + const result = op.select(a, b, c) + return result + } + + @arc4.abimethod() + public verify_setbit_bytes(a: bytes, b: uint64, c: uint64): bytes { + const result = op.setBit(a, b, c) + return result + } + + @arc4.abimethod() + public verify_setbit_uint64(a: uint64, b: uint64, c: uint64): uint64 { + const result = op.setBit(a, b, c) + return result + } + + @arc4.abimethod() + public verify_setbyte(a: bytes, b: uint64, c: uint64): bytes { + const result = op.setByte(a, b, c) + return result + } + + @arc4.abimethod() + public verify_shl(a: uint64, b: uint64): uint64 { + const result = op.shl(a, b) + return result + } + + @arc4.abimethod() + public verify_shr(a: uint64, b: uint64): uint64 { + const result = op.shr(a, b) + return result + } + + @arc4.abimethod() + public verify_sqrt(a: uint64): uint64 { + const result = op.sqrt(a) + return result + } + + @arc4.abimethod() + public verify_substring(a: bytes, b: uint64, c: uint64): bytes { + const result = op.substring(a, b, c) + return result + } +} diff --git a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal index 070046d..2fb67ab 100644 --- a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal +++ b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal @@ -1,66 +1,40 @@ #pragma version 10 -tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.approval_program: - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): +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 main_bare_routing@41 - 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_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[]" - method "verify_json_ref_string(byte[],byte[])byte[]" - method "verify_json_ref_uint64(byte[],byte[])uint64" - method "verify_json_ref_object(byte[],byte[])byte[]" + bz __puya_arc4_router___bare_routing@38 + pushbytess 0x45847eea 0xf57aceb5 0x7d631730 0xa1b24441 0xcd7be1ac 0x7cfda64b 0x54a910d9 0xc46568de 0x7a46a6ae 0x04372209 0x7e5f6d72 0x24ebcf84 0x9c0b3397 0x0ad40da4 0x95178870 0xdeedc99b 0xab2150bb 0x02a54017 0x3db66b41 0xc7ea8c2a 0x1dcea50c 0x16166f9a 0x2f472065 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_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 main_verify_addw_route@2 main_verify_base64_decode_standard_route@3 main_verify_base64_decode_url_route@4 main_verify_bytes_bitlen_route@5 main_verify_uint64_bitlen_route@6 main_verify_bsqrt_route@7 main_verify_btoi_route@8 main_verify_bzero_route@9 main_verify_concat_route@10 main_verify_divmodw_route@11 main_verify_divw_route@12 main_verify_err_route@13 main_verify_exp_route@14 main_verify_expw_route@15 main_verify_extract_route@16 main_verify_extract_from_2_route@17 main_verify_extract_uint16_route@18 main_verify_extract_uint32_route@19 main_verify_extract_uint64_route@20 main_verify_getbit_bytes_route@21 main_verify_getbit_uint64_route@22 main_verify_getbyte_route@23 main_verify_itob_route@24 main_verify_mulw_route@25 main_verify_replace_route@26 main_verify_select_bytes_route@27 main_verify_select_uint64_route@28 main_verify_setbit_bytes_route@29 main_verify_setbit_uint64_route@30 main_verify_setbyte_route@31 main_verify_shl_route@32 main_verify_shr_route@33 main_verify_sqrt_route@34 main_verify_substring_route@35 main_verify_json_ref_string_route@36 main_verify_json_ref_uint64_route@37 main_verify_json_ref_object_route@38 - err // reject transaction + 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_mulw_route@25 __puya_arc4_router___verify_replace_route@26 __puya_arc4_router___verify_select_bytes_route@27 __puya_arc4_router___verify_select_uint64_route@28 __puya_arc4_router___verify_setbit_bytes_route@29 __puya_arc4_router___verify_setbit_uint64_route@30 __puya_arc4_router___verify_setbyte_route@31 __puya_arc4_router___verify_shl_route@32 __puya_arc4_router___verify_shr_route@33 __puya_arc4_router___verify_sqrt_route@34 __puya_arc4_router___verify_substring_route@35 + intc_1 // 0 + retsub -main_verify_addw_route@2: - // tests/artifacts/MiscellaneousOps/contract.py:5 +__puya_arc4_router___verify_addw_route@2: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:4 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/MiscellaneousOps/contract.py:5 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:4 // @arc4.abimethod() callsub verify_addw swap @@ -68,26 +42,26 @@ main_verify_addw_route@2: swap itob concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_base64_decode_standard_route@3: - // tests/artifacts/MiscellaneousOps/contract.py:10 +__puya_arc4_router___verify_base64_decode_standard_route@3: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:10 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/MiscellaneousOps/contract.py:10 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:10 // @arc4.abimethod() callsub verify_base64_decode_standard dup @@ -96,26 +70,26 @@ main_verify_base64_decode_standard_route@3: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_base64_decode_url_route@4: - // tests/artifacts/MiscellaneousOps/contract.py:15 +__puya_arc4_router___verify_base64_decode_url_route@4: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:16 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/MiscellaneousOps/contract.py:15 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:16 // @arc4.abimethod() callsub verify_base64_decode_url dup @@ -124,74 +98,74 @@ main_verify_base64_decode_url_route@4: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bytes_bitlen_route@5: - // tests/artifacts/MiscellaneousOps/contract.py:20 +__puya_arc4_router___verify_bytes_bitlen_route@5: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:22 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:20 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:22 // @arc4.abimethod() callsub verify_bytes_bitlen itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_bitlen_route@6: - // tests/artifacts/MiscellaneousOps/contract.py:26 +__puya_arc4_router___verify_uint64_bitlen_route@6: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:29 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi - // tests/artifacts/MiscellaneousOps/contract.py:26 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:29 // @arc4.abimethod() callsub verify_uint64_bitlen itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bsqrt_route@7: - // tests/artifacts/MiscellaneousOps/contract.py:31 +__puya_arc4_router___verify_bsqrt_route@7: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:35 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/MiscellaneousOps/contract.py:31 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:35 // @arc4.abimethod() callsub verify_bsqrt dup @@ -200,49 +174,49 @@ main_verify_bsqrt_route@7: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_btoi_route@8: - // tests/artifacts/MiscellaneousOps/contract.py:37 +__puya_arc4_router___verify_btoi_route@8: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:42 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/MiscellaneousOps/contract.py:37 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:42 // @arc4.abimethod() callsub verify_btoi itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bzero_route@9: - // tests/artifacts/MiscellaneousOps/contract.py:42 +__puya_arc4_router___verify_bzero_route@9: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:48 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi - // tests/artifacts/MiscellaneousOps/contract.py:42 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:48 // @arc4.abimethod() callsub verify_bzero dup @@ -251,23 +225,23 @@ main_verify_bzero_route@9: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_concat_route@10: - // tests/artifacts/MiscellaneousOps/contract.py:47 +__puya_arc4_router___verify_concat_route@10: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:54 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 @@ -276,7 +250,7 @@ main_verify_concat_route@10: btoi txna ApplicationArgs 4 btoi - // tests/artifacts/MiscellaneousOps/contract.py:47 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:54 // @arc4.abimethod() callsub verify_concat dup @@ -285,23 +259,23 @@ main_verify_concat_route@10: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_divmodw_route@11: - // tests/artifacts/MiscellaneousOps/contract.py:55 +__puya_arc4_router___verify_divmodw_route@11: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:63 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 @@ -310,64 +284,60 @@ main_verify_divmodw_route@11: btoi txna ApplicationArgs 4 btoi - // tests/artifacts/MiscellaneousOps/contract.py:55 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:63 // @arc4.abimethod() callsub verify_divmodw - cover 3 - cover 2 - swap + uncover 3 itob - cover 2 + uncover 3 itob - swap + uncover 3 itob - swap uncover 3 itob - cover 3 - uncover 2 - swap + uncover 3 + uncover 3 concat - swap + uncover 2 concat swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_divw_route@12: - // tests/artifacts/MiscellaneousOps/contract.py:62 +__puya_arc4_router___verify_divw_route@12: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:69 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:62 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:69 // @arc4.abimethod() callsub verify_divw itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_err_route@13: - // tests/artifacts/MiscellaneousOps/contract.py:67 +__puya_arc4_router___verify_err_route@13: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:75 // @arc4.abimethod() txn OnCompletion ! @@ -375,49 +345,49 @@ main_verify_err_route@13: txn ApplicationID assert // is not creating callsub verify_err - int 1 - return + intc_0 // 1 + retsub -main_verify_exp_route@14: - // tests/artifacts/MiscellaneousOps/contract.py:71 +__puya_arc4_router___verify_exp_route@14: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:80 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/MiscellaneousOps/contract.py:71 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:80 // @arc4.abimethod() callsub verify_exp itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_expw_route@15: - // tests/artifacts/MiscellaneousOps/contract.py:76 +__puya_arc4_router___verify_expw_route@15: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:86 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/MiscellaneousOps/contract.py:76 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:86 // @arc4.abimethod() callsub verify_expw swap @@ -425,30 +395,30 @@ main_verify_expw_route@15: swap itob concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_extract_route@16: - // tests/artifacts/MiscellaneousOps/contract.py:81 +__puya_arc4_router___verify_extract_route@16: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:92 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:81 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:92 // @arc4.abimethod() callsub verify_extract dup @@ -457,26 +427,26 @@ main_verify_extract_route@16: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_extract_from_2_route@17: - // tests/artifacts/MiscellaneousOps/contract.py:86 +__puya_arc4_router___verify_extract_from_2_route@17: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:98 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/MiscellaneousOps/contract.py:86 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:98 // @arc4.abimethod() callsub verify_extract_from_2 dup @@ -485,176 +455,176 @@ main_verify_extract_from_2_route@17: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_extract_uint16_route@18: - // tests/artifacts/MiscellaneousOps/contract.py:91 +__puya_arc4_router___verify_extract_uint16_route@18: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:104 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:91 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:104 // @arc4.abimethod() callsub verify_extract_uint16 itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_extract_uint32_route@19: - // tests/artifacts/MiscellaneousOps/contract.py:96 +__puya_arc4_router___verify_extract_uint32_route@19: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:110 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:96 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:110 // @arc4.abimethod() callsub verify_extract_uint32 itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_extract_uint64_route@20: - // tests/artifacts/MiscellaneousOps/contract.py:101 +__puya_arc4_router___verify_extract_uint64_route@20: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:116 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:101 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:116 // @arc4.abimethod() callsub verify_extract_uint64 itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_getbit_bytes_route@21: - // tests/artifacts/MiscellaneousOps/contract.py:106 +__puya_arc4_router___verify_getbit_bytes_route@21: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:122 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:106 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:122 // @arc4.abimethod() callsub verify_getbit_bytes itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_getbit_uint64_route@22: - // tests/artifacts/MiscellaneousOps/contract.py:111 +__puya_arc4_router___verify_getbit_uint64_route@22: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:128 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/MiscellaneousOps/contract.py:111 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:128 // @arc4.abimethod() callsub verify_getbit_uint64 itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_getbyte_route@23: - // tests/artifacts/MiscellaneousOps/contract.py:116 +__puya_arc4_router___verify_getbyte_route@23: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:134 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:116 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:134 // @arc4.abimethod() callsub verify_getbyte itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_itob_route@24: - // tests/artifacts/MiscellaneousOps/contract.py:121 +__puya_arc4_router___verify_itob_route@24: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:140 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi - // tests/artifacts/MiscellaneousOps/contract.py:121 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:140 // @arc4.abimethod() callsub verify_itob dup @@ -663,28 +633,28 @@ main_verify_itob_route@24: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_mulw_route@25: - // tests/artifacts/MiscellaneousOps/contract.py:126 +__puya_arc4_router___verify_mulw_route@25: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:146 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/MiscellaneousOps/contract.py:126 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:146 // @arc4.abimethod() callsub verify_mulw swap @@ -692,30 +662,30 @@ main_verify_mulw_route@25: swap itob concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_replace_route@26: - // tests/artifacts/MiscellaneousOps/contract.py:131 +__puya_arc4_router___verify_replace_route@26: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:152 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:131 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:152 // @arc4.abimethod() callsub verify_replace dup @@ -724,30 +694,30 @@ main_verify_replace_route@26: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_select_bytes_route@27: - // tests/artifacts/MiscellaneousOps/contract.py:136 +__puya_arc4_router___verify_select_bytes_route@27: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:158 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:136 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:158 // @arc4.abimethod() callsub verify_select_bytes dup @@ -756,57 +726,57 @@ main_verify_select_bytes_route@27: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_select_uint64_route@28: - // tests/artifacts/MiscellaneousOps/contract.py:141 +__puya_arc4_router___verify_select_uint64_route@28: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:164 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:141 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:164 // @arc4.abimethod() callsub verify_select_uint64 itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_setbit_bytes_route@29: - // tests/artifacts/MiscellaneousOps/contract.py:146 +__puya_arc4_router___verify_setbit_bytes_route@29: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:170 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:146 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:170 // @arc4.abimethod() callsub verify_setbit_bytes dup @@ -815,57 +785,57 @@ main_verify_setbit_bytes_route@29: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_setbit_uint64_route@30: - // tests/artifacts/MiscellaneousOps/contract.py:151 +__puya_arc4_router___verify_setbit_uint64_route@30: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:176 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:151 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:176 // @arc4.abimethod() callsub verify_setbit_uint64 itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_setbyte_route@31: - // tests/artifacts/MiscellaneousOps/contract.py:156 +__puya_arc4_router___verify_setbyte_route@31: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:182 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:156 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:182 // @arc4.abimethod() callsub verify_setbyte dup @@ -874,103 +844,103 @@ main_verify_setbyte_route@31: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_shl_route@32: - // tests/artifacts/MiscellaneousOps/contract.py:161 +__puya_arc4_router___verify_shl_route@32: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:188 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/MiscellaneousOps/contract.py:161 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:188 // @arc4.abimethod() callsub verify_shl itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_shr_route@33: - // tests/artifacts/MiscellaneousOps/contract.py:166 +__puya_arc4_router___verify_shr_route@33: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:194 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/MiscellaneousOps/contract.py:166 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:194 // @arc4.abimethod() callsub verify_shr itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_sqrt_route@34: - // tests/artifacts/MiscellaneousOps/contract.py:171 +__puya_arc4_router___verify_sqrt_route@34: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:200 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi - // tests/artifacts/MiscellaneousOps/contract.py:171 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:200 // @arc4.abimethod() callsub verify_sqrt itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_substring_route@35: - // tests/artifacts/MiscellaneousOps/contract.py:176 +__puya_arc4_router___verify_substring_route@35: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:206 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): + // 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/MiscellaneousOps/contract.py:176 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:206 // @arc4.abimethod() callsub verify_substring dup @@ -979,721 +949,585 @@ main_verify_substring_route@35: extract 6 2 swap concat - byte 0x151f7c75 - swap - concat - log - int 1 - return - -main_verify_json_ref_string_route@36: - // tests/artifacts/MiscellaneousOps/contract.py:181 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/MiscellaneousOps/contract.py:181 - // @arc4.abimethod() - callsub verify_json_ref_string - dup - len - itob - extract 6 2 - swap - concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return - -main_verify_json_ref_uint64_route@37: - // tests/artifacts/MiscellaneousOps/contract.py:186 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/MiscellaneousOps/contract.py:186 - // @arc4.abimethod() - callsub verify_json_ref_uint64 - itob - byte 0x151f7c75 - swap - concat - log - int 1 - return - -main_verify_json_ref_object_route@38: - // tests/artifacts/MiscellaneousOps/contract.py:191 - // @arc4.abimethod() - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/MiscellaneousOps/contract.py:191 - // @arc4.abimethod() - callsub verify_json_ref_object - dup - len - itob - extract 6 2 - swap - concat - byte 0x151f7c75 - swap - concat - log - int 1 - return + intc_0 // 1 + retsub -main_bare_routing@41: - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): +__puya_arc4_router___bare_routing@38: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { txn OnCompletion - ! - assert // reject transaction + bnz __puya_arc4_router___after_if_else@42 txn ApplicationID ! assert // is creating - int 1 - return + intc_0 // 1 + retsub + +__puya_arc4_router___after_if_else@42: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 + // export class MiscellaneousOpsContract extends arc4.Contract { + intc_1 // 0 + retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_addw(a: uint64, b: uint64) -> uint64, uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_addw(a: uint64, b: uint64) -> uint64, uint64: verify_addw: - // tests/artifacts/MiscellaneousOps/contract.py:5-6 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:4-5 // @arc4.abimethod() - // def verify_addw(self, a: UInt64, b: UInt64) -> tuple[UInt64, UInt64]: + // public verify_addw(a: uint64, b: uint64): readonly [uint64, uint64] { proto 2 2 - // tests/artifacts/MiscellaneousOps/contract.py:7 - // result = op.addw(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:6 + // const result = op.addw(a, b) frame_dig -2 frame_dig -1 addw - // tests/artifacts/MiscellaneousOps/contract.py:8 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:7 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_base64_decode_standard(a: bytes) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_base64_decode_standard(a: bytes) -> bytes: verify_base64_decode_standard: - // tests/artifacts/MiscellaneousOps/contract.py:10-11 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:10-11 // @arc4.abimethod() - // def verify_base64_decode_standard(self, a: Bytes) -> Bytes: + // public verify_base64_decode_standard(a: bytes): bytes { proto 1 1 - // tests/artifacts/MiscellaneousOps/contract.py:12 - // result = op.base64_decode(op.Base64.StdEncoding, a) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:12 + // const result = op.base64Decode(Base64.StdEncoding, a) frame_dig -1 base64_decode StdEncoding - // tests/artifacts/MiscellaneousOps/contract.py:13 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:13 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_base64_decode_url(a: bytes) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_base64_decode_url(a: bytes) -> bytes: verify_base64_decode_url: - // tests/artifacts/MiscellaneousOps/contract.py:15-16 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:16-17 // @arc4.abimethod() - // def verify_base64_decode_url(self, a: Bytes) -> Bytes: + // public verify_base64_decode_url(a: bytes): bytes { proto 1 1 - // tests/artifacts/MiscellaneousOps/contract.py:17 - // result = op.base64_decode(op.Base64.URLEncoding, a) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:18 + // const result = op.base64Decode(Base64.URLEncoding, a) frame_dig -1 base64_decode URLEncoding - // tests/artifacts/MiscellaneousOps/contract.py:18 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:19 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_bytes_bitlen(a: bytes, pad_a_size: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_bytes_bitlen(a: bytes, pad_a_size: uint64) -> uint64: verify_bytes_bitlen: - // tests/artifacts/MiscellaneousOps/contract.py:20-21 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:22-23 // @arc4.abimethod() - // def verify_bytes_bitlen(self, a: Bytes, pad_a_size: UInt64) -> UInt64: + // public verify_bytes_bitlen(a: bytes, pad_a_size: uint64): uint64 { proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:22 - // a = op.bzero(pad_a_size) + a + // 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 - dup - frame_bury -2 - // tests/artifacts/MiscellaneousOps/contract.py:23 - // result = op.bitlen(a) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:25 + // const result = op.bitLength(paddedA) bitlen - // tests/artifacts/MiscellaneousOps/contract.py:24 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:26 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_uint64_bitlen(a: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_uint64_bitlen(a: uint64) -> uint64: verify_uint64_bitlen: - // tests/artifacts/MiscellaneousOps/contract.py:26-27 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:29-30 // @arc4.abimethod() - // def verify_uint64_bitlen(self, a: UInt64) -> UInt64: + // public verify_uint64_bitlen(a: uint64): uint64 { proto 1 1 - // tests/artifacts/MiscellaneousOps/contract.py:28 - // result = op.bitlen(a) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:31 + // const result = op.bitLength(a) frame_dig -1 bitlen - // tests/artifacts/MiscellaneousOps/contract.py:29 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:32 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_bsqrt(a: bytes) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_bsqrt(a: bytes) -> bytes: verify_bsqrt: - // tests/artifacts/MiscellaneousOps/contract.py:31-32 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:35-36 // @arc4.abimethod() - // def verify_bsqrt(self, a: Bytes) -> Bytes: + // public verify_bsqrt(a: bytes): bytes { proto 1 1 - // tests/artifacts/MiscellaneousOps/contract.py:34 - // result = op.bsqrt(a_biguint) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:38 + // const result = op.bsqrt(a_biguint) frame_dig -1 bsqrt - // tests/artifacts/MiscellaneousOps/contract.py:35 - // return result.bytes + // tests/artifacts/miscellaneous-ops/contract.algo.ts:39 + // return Bytes(result) retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_btoi(a: bytes) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_btoi(a: bytes) -> uint64: verify_btoi: - // tests/artifacts/MiscellaneousOps/contract.py:37-38 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:42-43 // @arc4.abimethod() - // def verify_btoi(self, a: Bytes) -> UInt64: + // public verify_btoi(a: bytes): uint64 { proto 1 1 - // tests/artifacts/MiscellaneousOps/contract.py:39 - // result = op.btoi(a) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:44 + // const result = op.btoi(a) frame_dig -1 btoi - // tests/artifacts/MiscellaneousOps/contract.py:40 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:45 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_bzero(a: uint64) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_bzero(a: uint64) -> bytes: verify_bzero: - // tests/artifacts/MiscellaneousOps/contract.py:42-43 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:48-49 // @arc4.abimethod() - // def verify_bzero(self, a: UInt64) -> Bytes: + // public verify_bzero(a: uint64): bytes { proto 1 1 - // tests/artifacts/MiscellaneousOps/contract.py:44 - // result = op.bzero(a) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:50 + // const result = op.bzero(a) frame_dig -1 bzero - // tests/artifacts/MiscellaneousOps/contract.py:45 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:51 // return op.sha256(result) sha256 retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_concat(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64) -> bytes: +// 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/MiscellaneousOps/contract.py:47-48 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:54-55 // @arc4.abimethod() - // def verify_concat(self, a: Bytes, b: Bytes, pad_a_size: UInt64, pad_b_size: UInt64) -> Bytes: + // public verify_concat(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64): bytes { proto 4 1 - // tests/artifacts/MiscellaneousOps/contract.py:49 - // a = op.bzero(pad_a_size) + a + // 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 - frame_bury -4 - // tests/artifacts/MiscellaneousOps/contract.py:50 - // b = op.bzero(pad_b_size) + b + // 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 - frame_bury -3 - // tests/artifacts/MiscellaneousOps/contract.py:51 - // result = a + b - frame_dig -4 - frame_dig -3 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:58 + // const result = paddedA.concat(paddedB) concat - // tests/artifacts/MiscellaneousOps/contract.py:52 - // result = op.sha256(result) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:59 + // const resultHash = op.sha256(result) sha256 - // tests/artifacts/MiscellaneousOps/contract.py:53 - // return result + // tests/artifacts/miscellaneous-ops/contract.algo.ts:60 + // return resultHash retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_divmodw(a: uint64, b: uint64, c: uint64, d: uint64) -> uint64, uint64, uint64, uint64: +// 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/MiscellaneousOps/contract.py:55-58 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:63-64 // @arc4.abimethod() - // def verify_divmodw( - // self, a: UInt64, b: UInt64, c: UInt64, d: UInt64 - // ) -> tuple[UInt64, UInt64, UInt64, UInt64]: + // public verify_divmodw(a: uint64, b: uint64, c: uint64, d: uint64): readonly [uint64, uint64, uint64, uint64] { proto 4 4 - // tests/artifacts/MiscellaneousOps/contract.py:59 - // result = op.divmodw(a, b, c, d) + // 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/MiscellaneousOps/contract.py:60 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:66 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_divw(a: uint64, b: uint64, c: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_divw(a: uint64, b: uint64, c: uint64) -> uint64: verify_divw: - // tests/artifacts/MiscellaneousOps/contract.py:62-63 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:69-70 // @arc4.abimethod() - // def verify_divw(self, a: UInt64, b: UInt64, c: UInt64) -> UInt64: + // public verify_divw(a: uint64, b: uint64, c: uint64): uint64 { proto 3 1 - // tests/artifacts/MiscellaneousOps/contract.py:64 - // result = op.divw(a, b, c) + // 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/MiscellaneousOps/contract.py:65 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:72 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_err() -> void: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_err() -> void: verify_err: - // tests/artifacts/MiscellaneousOps/contract.py:67-68 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:75-76 // @arc4.abimethod() - // def verify_err(self) -> None: + // public verify_err(): void { proto 0 0 - // tests/artifacts/MiscellaneousOps/contract.py:69 - // op.err() + // tests/artifacts/miscellaneous-ops/contract.algo.ts:77 + // err() err -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_exp(a: uint64, b: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_exp(a: uint64, b: uint64) -> uint64: verify_exp: - // tests/artifacts/MiscellaneousOps/contract.py:71-72 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:80-81 // @arc4.abimethod() - // def verify_exp(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_exp(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:73 - // result = op.exp(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:82 + // const result = op.exp(a, b) frame_dig -2 frame_dig -1 exp - // tests/artifacts/MiscellaneousOps/contract.py:74 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:83 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_expw(a: uint64, b: uint64) -> uint64, uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_expw(a: uint64, b: uint64) -> uint64, uint64: verify_expw: - // tests/artifacts/MiscellaneousOps/contract.py:76-77 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:86-87 // @arc4.abimethod() - // def verify_expw(self, a: UInt64, b: UInt64) -> tuple[UInt64, UInt64]: + // public verify_expw(a: uint64, b: uint64): readonly [uint64, uint64] { proto 2 2 - // tests/artifacts/MiscellaneousOps/contract.py:78 - // result = op.expw(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:88 + // const result = op.expw(a, b) frame_dig -2 frame_dig -1 expw - // tests/artifacts/MiscellaneousOps/contract.py:79 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:89 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_extract(a: bytes, b: uint64, c: uint64) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_extract(a: bytes, b: uint64, c: uint64) -> bytes: verify_extract: - // tests/artifacts/MiscellaneousOps/contract.py:81-82 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:92-93 // @arc4.abimethod() - // def verify_extract(self, a: Bytes, b: UInt64, c: UInt64) -> Bytes: + // public verify_extract(a: bytes, b: uint64, c: uint64): bytes { proto 3 1 - // tests/artifacts/MiscellaneousOps/contract.py:83 - // result = op.extract(a, b, c) + // 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/MiscellaneousOps/contract.py:84 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:95 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_extract_from_2(a: bytes) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_extract_from_2(a: bytes) -> bytes: verify_extract_from_2: - // tests/artifacts/MiscellaneousOps/contract.py:86-87 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:98-99 // @arc4.abimethod() - // def verify_extract_from_2(self, a: Bytes) -> Bytes: + // public verify_extract_from_2(a: bytes): bytes { proto 1 1 - // tests/artifacts/MiscellaneousOps/contract.py:88 - // result = op.extract(a, 2, 0) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:100 + // const result = op.extract(a, 2, 0) frame_dig -1 extract 2 0 - // tests/artifacts/MiscellaneousOps/contract.py:89 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:101 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_extract_uint16(a: bytes, b: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_extract_uint16(a: bytes, b: uint64) -> uint64: verify_extract_uint16: - // tests/artifacts/MiscellaneousOps/contract.py:91-92 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:104-105 // @arc4.abimethod() - // def verify_extract_uint16(self, a: Bytes, b: UInt64) -> UInt64: + // public verify_extract_uint16(a: bytes, b: uint64): uint64 { proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:93 - // result = op.extract_uint16(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:106 + // const result = op.extractUint16(a, b) frame_dig -2 frame_dig -1 extract_uint16 - // tests/artifacts/MiscellaneousOps/contract.py:94 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:107 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_extract_uint32(a: bytes, b: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_extract_uint32(a: bytes, b: uint64) -> uint64: verify_extract_uint32: - // tests/artifacts/MiscellaneousOps/contract.py:96-97 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:110-111 // @arc4.abimethod() - // def verify_extract_uint32(self, a: Bytes, b: UInt64) -> UInt64: + // public verify_extract_uint32(a: bytes, b: uint64): uint64 { proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:98 - // result = op.extract_uint32(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:112 + // const result = op.extractUint32(a, b) frame_dig -2 frame_dig -1 extract_uint32 - // tests/artifacts/MiscellaneousOps/contract.py:99 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:113 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_extract_uint64(a: bytes, b: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_extract_uint64(a: bytes, b: uint64) -> uint64: verify_extract_uint64: - // tests/artifacts/MiscellaneousOps/contract.py:101-102 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:116-117 // @arc4.abimethod() - // def verify_extract_uint64(self, a: Bytes, b: UInt64) -> UInt64: + // public verify_extract_uint64(a: bytes, b: uint64): uint64 { proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:103 - // result = op.extract_uint64(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:118 + // const result = op.extractUint64(a, b) frame_dig -2 frame_dig -1 extract_uint64 - // tests/artifacts/MiscellaneousOps/contract.py:104 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:119 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_getbit_bytes(a: bytes, b: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_getbit_bytes(a: bytes, b: uint64) -> uint64: verify_getbit_bytes: - // tests/artifacts/MiscellaneousOps/contract.py:106-107 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:122-123 // @arc4.abimethod() - // def verify_getbit_bytes(self, a: Bytes, b: UInt64) -> UInt64: + // public verify_getbit_bytes(a: bytes, b: uint64): uint64 { proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:108 - // result = op.getbit(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:124 + // const result = op.getBit(a, b) frame_dig -2 frame_dig -1 getbit - // tests/artifacts/MiscellaneousOps/contract.py:109 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:125 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_getbit_uint64(a: uint64, b: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_getbit_uint64(a: uint64, b: uint64) -> uint64: verify_getbit_uint64: - // tests/artifacts/MiscellaneousOps/contract.py:111-112 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:128-129 // @arc4.abimethod() - // def verify_getbit_uint64(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_getbit_uint64(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:113 - // result = op.getbit(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:130 + // const result = op.getBit(a, b) frame_dig -2 frame_dig -1 getbit - // tests/artifacts/MiscellaneousOps/contract.py:114 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:131 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_getbyte(a: bytes, b: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_getbyte(a: bytes, b: uint64) -> uint64: verify_getbyte: - // tests/artifacts/MiscellaneousOps/contract.py:116-117 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:134-135 // @arc4.abimethod() - // def verify_getbyte(self, a: Bytes, b: UInt64) -> UInt64: + // public verify_getbyte(a: bytes, b: uint64): uint64 { proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:118 - // result = op.getbyte(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:136 + // const result = op.getByte(a, b) frame_dig -2 frame_dig -1 getbyte - // tests/artifacts/MiscellaneousOps/contract.py:119 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:137 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_itob(a: uint64) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_itob(a: uint64) -> bytes: verify_itob: - // tests/artifacts/MiscellaneousOps/contract.py:121-122 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:140-141 // @arc4.abimethod() - // def verify_itob(self, a: UInt64) -> Bytes: + // public verify_itob(a: uint64): bytes { proto 1 1 - // tests/artifacts/MiscellaneousOps/contract.py:123 - // result = op.itob(a) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:142 + // const result = op.itob(a) frame_dig -1 itob - // tests/artifacts/MiscellaneousOps/contract.py:124 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:143 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_mulw(a: uint64, b: uint64) -> uint64, uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_mulw(a: uint64, b: uint64) -> uint64, uint64: verify_mulw: - // tests/artifacts/MiscellaneousOps/contract.py:126-127 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:146-147 // @arc4.abimethod() - // def verify_mulw(self, a: UInt64, b: UInt64) -> tuple[UInt64, UInt64]: + // public verify_mulw(a: uint64, b: uint64): readonly [uint64, uint64] { proto 2 2 - // tests/artifacts/MiscellaneousOps/contract.py:128 - // result = op.mulw(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:148 + // const result = op.mulw(a, b) frame_dig -2 frame_dig -1 mulw - // tests/artifacts/MiscellaneousOps/contract.py:129 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:149 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_replace(a: bytes, b: uint64, c: bytes) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_replace(a: bytes, b: uint64, c: bytes) -> bytes: verify_replace: - // tests/artifacts/MiscellaneousOps/contract.py:131-132 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:152-153 // @arc4.abimethod() - // def verify_replace(self, a: Bytes, b: UInt64, c: Bytes) -> Bytes: + // public verify_replace(a: bytes, b: uint64, c: bytes): bytes { proto 3 1 - // tests/artifacts/MiscellaneousOps/contract.py:133 - // result = op.replace(a, b, c) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:154 + // const result = op.replace(a, b, c) frame_dig -3 frame_dig -2 frame_dig -1 replace3 - // tests/artifacts/MiscellaneousOps/contract.py:134 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:155 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_select_bytes(a: bytes, b: bytes, c: uint64) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_select_bytes(a: bytes, b: bytes, c: uint64) -> bytes: verify_select_bytes: - // tests/artifacts/MiscellaneousOps/contract.py:136-137 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:158-159 // @arc4.abimethod() - // def verify_select_bytes(self, a: Bytes, b: Bytes, c: UInt64) -> Bytes: + // public verify_select_bytes(a: bytes, b: bytes, c: uint64): bytes { proto 3 1 - // tests/artifacts/MiscellaneousOps/contract.py:138 - // result = op.select_bytes(a, b, c) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:160 + // const result = op.select(a, b, c) frame_dig -3 frame_dig -2 frame_dig -1 select - // tests/artifacts/MiscellaneousOps/contract.py:139 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:161 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_select_uint64(a: uint64, b: uint64, c: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_select_uint64(a: uint64, b: uint64, c: uint64) -> uint64: verify_select_uint64: - // tests/artifacts/MiscellaneousOps/contract.py:141-142 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:164-165 // @arc4.abimethod() - // def verify_select_uint64(self, a: UInt64, b: UInt64, c: UInt64) -> UInt64: + // public verify_select_uint64(a: uint64, b: uint64, c: uint64): uint64 { proto 3 1 - // tests/artifacts/MiscellaneousOps/contract.py:143 - // result = op.select_uint64(a, b, c) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:166 + // const result = op.select(a, b, c) frame_dig -3 frame_dig -2 frame_dig -1 select - // tests/artifacts/MiscellaneousOps/contract.py:144 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:167 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_setbit_bytes(a: bytes, b: uint64, c: uint64) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_setbit_bytes(a: bytes, b: uint64, c: uint64) -> bytes: verify_setbit_bytes: - // tests/artifacts/MiscellaneousOps/contract.py:146-147 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:170-171 // @arc4.abimethod() - // def verify_setbit_bytes(self, a: Bytes, b: UInt64, c: UInt64) -> Bytes: + // public verify_setbit_bytes(a: bytes, b: uint64, c: uint64): bytes { proto 3 1 - // tests/artifacts/MiscellaneousOps/contract.py:148 - // result = op.setbit_bytes(a, b, c) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:172 + // const result = op.setBit(a, b, c) frame_dig -3 frame_dig -2 frame_dig -1 setbit - // tests/artifacts/MiscellaneousOps/contract.py:149 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:173 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_setbit_uint64(a: uint64, b: uint64, c: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_setbit_uint64(a: uint64, b: uint64, c: uint64) -> uint64: verify_setbit_uint64: - // tests/artifacts/MiscellaneousOps/contract.py:151-152 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:176-177 // @arc4.abimethod() - // def verify_setbit_uint64(self, a: UInt64, b: UInt64, c: UInt64) -> UInt64: + // public verify_setbit_uint64(a: uint64, b: uint64, c: uint64): uint64 { proto 3 1 - // tests/artifacts/MiscellaneousOps/contract.py:153 - // result = op.setbit_uint64(a, b, c) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:178 + // const result = op.setBit(a, b, c) frame_dig -3 frame_dig -2 frame_dig -1 setbit - // tests/artifacts/MiscellaneousOps/contract.py:154 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:179 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_setbyte(a: bytes, b: uint64, c: uint64) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_setbyte(a: bytes, b: uint64, c: uint64) -> bytes: verify_setbyte: - // tests/artifacts/MiscellaneousOps/contract.py:156-157 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:182-183 // @arc4.abimethod() - // def verify_setbyte(self, a: Bytes, b: UInt64, c: UInt64) -> Bytes: + // public verify_setbyte(a: bytes, b: uint64, c: uint64): bytes { proto 3 1 - // tests/artifacts/MiscellaneousOps/contract.py:158 - // result = op.setbyte(a, b, c) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:184 + // const result = op.setByte(a, b, c) frame_dig -3 frame_dig -2 frame_dig -1 setbyte - // tests/artifacts/MiscellaneousOps/contract.py:159 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:185 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_shl(a: uint64, b: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_shl(a: uint64, b: uint64) -> uint64: verify_shl: - // tests/artifacts/MiscellaneousOps/contract.py:161-162 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:188-189 // @arc4.abimethod() - // def verify_shl(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_shl(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:163 - // result = op.shl(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:190 + // const result = op.shl(a, b) frame_dig -2 frame_dig -1 shl - // tests/artifacts/MiscellaneousOps/contract.py:164 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:191 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_shr(a: uint64, b: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_shr(a: uint64, b: uint64) -> uint64: verify_shr: - // tests/artifacts/MiscellaneousOps/contract.py:166-167 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:194-195 // @arc4.abimethod() - // def verify_shr(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_shr(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:168 - // result = op.shr(a, b) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:196 + // const result = op.shr(a, b) frame_dig -2 frame_dig -1 shr - // tests/artifacts/MiscellaneousOps/contract.py:169 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:197 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_sqrt(a: uint64) -> uint64: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_sqrt(a: uint64) -> uint64: verify_sqrt: - // tests/artifacts/MiscellaneousOps/contract.py:171-172 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:200-201 // @arc4.abimethod() - // def verify_sqrt(self, a: UInt64) -> UInt64: + // public verify_sqrt(a: uint64): uint64 { proto 1 1 - // tests/artifacts/MiscellaneousOps/contract.py:173 - // result = op.sqrt(a) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:202 + // const result = op.sqrt(a) frame_dig -1 sqrt - // tests/artifacts/MiscellaneousOps/contract.py:174 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:203 // return result retsub -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_substring(a: bytes, b: uint64, c: uint64) -> bytes: +// tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.verify_substring(a: bytes, b: uint64, c: uint64) -> bytes: verify_substring: - // tests/artifacts/MiscellaneousOps/contract.py:176-177 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:206-207 // @arc4.abimethod() - // def verify_substring(self, a: Bytes, b: UInt64, c: UInt64) -> Bytes: + // public verify_substring(a: bytes, b: uint64, c: uint64): bytes { proto 3 1 - // tests/artifacts/MiscellaneousOps/contract.py:178 - // result = op.substring(a, b, c) + // tests/artifacts/miscellaneous-ops/contract.algo.ts:208 + // const result = op.substring(a, b, c) frame_dig -3 frame_dig -2 frame_dig -1 substring3 - // tests/artifacts/MiscellaneousOps/contract.py:179 - // return result - retsub - - -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_json_ref_string(a: bytes, b: bytes) -> bytes: -verify_json_ref_string: - // tests/artifacts/MiscellaneousOps/contract.py:181-182 - // @arc4.abimethod() - // def verify_json_ref_string(self, a: Bytes, b: Bytes) -> Bytes: - proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:183 - // result = op.JsonRef.json_string(a, b) - frame_dig -2 - frame_dig -1 - json_ref JSONString - // tests/artifacts/MiscellaneousOps/contract.py:184 - // return result - retsub - - -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_json_ref_uint64(a: bytes, b: bytes) -> uint64: -verify_json_ref_uint64: - // tests/artifacts/MiscellaneousOps/contract.py:186-187 - // @arc4.abimethod() - // def verify_json_ref_uint64(self, a: Bytes, b: Bytes) -> UInt64: - proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:188 - // result = op.JsonRef.json_uint64(a, b) - frame_dig -2 - frame_dig -1 - json_ref JSONUint64 - // tests/artifacts/MiscellaneousOps/contract.py:189 - // return result - retsub - - -// tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.verify_json_ref_object(a: bytes, b: bytes) -> bytes: -verify_json_ref_object: - // tests/artifacts/MiscellaneousOps/contract.py:191-192 - // @arc4.abimethod() - // def verify_json_ref_object(self, a: Bytes, b: Bytes) -> Bytes: - proto 2 1 - // tests/artifacts/MiscellaneousOps/contract.py:193 - // result = op.JsonRef.json_object(a, b) - frame_dig -2 - frame_dig -1 - json_ref JSONObject - // tests/artifacts/MiscellaneousOps/contract.py:194 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:209 // return result retsub diff --git a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json index 8a3e7d8..3825523 100644 --- a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json +++ b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json @@ -1,858 +1,792 @@ { - "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_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" - } - }, - "verify_json_ref_string(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_json_ref_uint64(byte[],byte[])uint64": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_json_ref_object(byte[],byte[])byte[]": { - "call_config": { - "no_op": "CALL" - } - } - }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDQxCiAgICBtZXRob2QgInZlcmlmeV9hZGR3KHVpbnQ2NCx1aW50NjQpKHVpbnQ2NCx1aW50NjQpIgogICAgbWV0aG9kICJ2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZChieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmFzZTY0X2RlY29kZV91cmwoYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2J5dGVzX2JpdGxlbihieXRlW10sdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9iaXRsZW4odWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2JzcXJ0KGJ5dGVbXSlieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9idG9pKGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9iemVybyh1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfY29uY2F0KGJ5dGVbXSxieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9kaXZtb2R3KHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCkodWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0KSIKICAgIG1ldGhvZCAidmVyaWZ5X2RpdncodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfZXJyKCl2b2lkIgogICAgbWV0aG9kICJ2ZXJpZnlfZXhwKHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfZXhwdyh1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0KSIKICAgIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3QoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF9mcm9tXzIoYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3RfdWludDE2KGJ5dGVbXSx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF91aW50MzIoYnl0ZVtdLHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9leHRyYWN0X3VpbnQ2NChieXRlW10sdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2dldGJpdF9ieXRlcyhieXRlW10sdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2dldGJpdF91aW50NjQodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9nZXRieXRlKGJ5dGVbXSx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfaXRvYih1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfbXVsdyh1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0KSIKICAgIG1ldGhvZCAidmVyaWZ5X3JlcGxhY2UoYnl0ZVtdLHVpbnQ2NCxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfc2VsZWN0X2J5dGVzKGJ5dGVbXSxieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X3NlbGVjdF91aW50NjQodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfc2V0Yml0X2J5dGVzKGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X3NldGJpdF91aW50NjQodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfc2V0Ynl0ZShieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9zaGwodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9zaHIodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9zcXJ0KHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9zdWJzdHJpbmcoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfanNvbl9yZWZfc3RyaW5nKGJ5dGVbXSxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfanNvbl9yZWZfdWludDY0KGJ5dGVbXSxieXRlW10pdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfanNvbl9yZWZfb2JqZWN0KGJ5dGVbXSxieXRlW10pYnl0ZVtdIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl92ZXJpZnlfYWRkd19yb3V0ZUAyIG1haW5fdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmRfcm91dGVAMyBtYWluX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybF9yb3V0ZUA0IG1haW5fdmVyaWZ5X2J5dGVzX2JpdGxlbl9yb3V0ZUA1IG1haW5fdmVyaWZ5X3VpbnQ2NF9iaXRsZW5fcm91dGVANiBtYWluX3ZlcmlmeV9ic3FydF9yb3V0ZUA3IG1haW5fdmVyaWZ5X2J0b2lfcm91dGVAOCBtYWluX3ZlcmlmeV9iemVyb19yb3V0ZUA5IG1haW5fdmVyaWZ5X2NvbmNhdF9yb3V0ZUAxMCBtYWluX3ZlcmlmeV9kaXZtb2R3X3JvdXRlQDExIG1haW5fdmVyaWZ5X2Rpdndfcm91dGVAMTIgbWFpbl92ZXJpZnlfZXJyX3JvdXRlQDEzIG1haW5fdmVyaWZ5X2V4cF9yb3V0ZUAxNCBtYWluX3ZlcmlmeV9leHB3X3JvdXRlQDE1IG1haW5fdmVyaWZ5X2V4dHJhY3Rfcm91dGVAMTYgbWFpbl92ZXJpZnlfZXh0cmFjdF9mcm9tXzJfcm91dGVAMTcgbWFpbl92ZXJpZnlfZXh0cmFjdF91aW50MTZfcm91dGVAMTggbWFpbl92ZXJpZnlfZXh0cmFjdF91aW50MzJfcm91dGVAMTkgbWFpbl92ZXJpZnlfZXh0cmFjdF91aW50NjRfcm91dGVAMjAgbWFpbl92ZXJpZnlfZ2V0Yml0X2J5dGVzX3JvdXRlQDIxIG1haW5fdmVyaWZ5X2dldGJpdF91aW50NjRfcm91dGVAMjIgbWFpbl92ZXJpZnlfZ2V0Ynl0ZV9yb3V0ZUAyMyBtYWluX3ZlcmlmeV9pdG9iX3JvdXRlQDI0IG1haW5fdmVyaWZ5X211bHdfcm91dGVAMjUgbWFpbl92ZXJpZnlfcmVwbGFjZV9yb3V0ZUAyNiBtYWluX3ZlcmlmeV9zZWxlY3RfYnl0ZXNfcm91dGVAMjcgbWFpbl92ZXJpZnlfc2VsZWN0X3VpbnQ2NF9yb3V0ZUAyOCBtYWluX3ZlcmlmeV9zZXRiaXRfYnl0ZXNfcm91dGVAMjkgbWFpbl92ZXJpZnlfc2V0Yml0X3VpbnQ2NF9yb3V0ZUAzMCBtYWluX3ZlcmlmeV9zZXRieXRlX3JvdXRlQDMxIG1haW5fdmVyaWZ5X3NobF9yb3V0ZUAzMiBtYWluX3ZlcmlmeV9zaHJfcm91dGVAMzMgbWFpbl92ZXJpZnlfc3FydF9yb3V0ZUAzNCBtYWluX3ZlcmlmeV9zdWJzdHJpbmdfcm91dGVAMzUgbWFpbl92ZXJpZnlfanNvbl9yZWZfc3RyaW5nX3JvdXRlQDM2IG1haW5fdmVyaWZ5X2pzb25fcmVmX3VpbnQ2NF9yb3V0ZUAzNyBtYWluX3ZlcmlmeV9qc29uX3JlZl9vYmplY3Rfcm91dGVAMzgKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X2FkZHdfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hZGR3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmRfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmFzZTY0X2RlY29kZV91cmxfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX2JpdGxlbl9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2JpdGxlbgogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludDY0X2JpdGxlbl9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2JpdGxlbgogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnNxcnRfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjMxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ic3FydAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J0b2lfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9idG9pCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iemVyb19yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnplcm8KICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9jb25jYXRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2NvbmNhdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Rpdm1vZHdfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo1NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9kaXZtb2R3CiAgICBjb3ZlciAzCiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb3ZlciAyCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIGNvdmVyIDMKICAgIHVuY292ZXIgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZGl2d19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2RpdncKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Vycl9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiB2ZXJpZnlfZXJyCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9leHBfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHAKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2V4cHdfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHB3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2V4dHJhY3Rfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXh0cmFjdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2V4dHJhY3RfZnJvbV8yX3JvdXRlQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6ODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo4NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfZnJvbV8yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZXh0cmFjdF91aW50MTZfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjkxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXh0cmFjdF91aW50MTYKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2V4dHJhY3RfdWludDMyX3JvdXRlQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6OTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfdWludDMyCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9leHRyYWN0X3VpbnQ2NF9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfdWludDY0CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRiaXRfYnl0ZXNfcm91dGVAMjE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRiaXRfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldGJpdF91aW50NjRfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjExMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldGJpdF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldGJ5dGVfcm91dGVAMjM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRieXRlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9pdG9iX3JvdXRlQDI0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9pdG9iCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfbXVsd19yb3V0ZUAyNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEyNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfbXVsdwogICAgc3dhcAogICAgaXRvYgogICAgc3dhcAogICAgaXRvYgogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9yZXBsYWNlX3JvdXRlQDI2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTMxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3JlcGxhY2UKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zZWxlY3RfYnl0ZXNfcm91dGVAMjc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTM2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2VsZWN0X2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2VsZWN0X3VpbnQ2NF9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2VsZWN0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2V0Yml0X2J5dGVzX3JvdXRlQDI5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2V0Yml0X2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2V0Yml0X3VpbnQ2NF9yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2V0Yml0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2V0Ynl0ZV9yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NldGJ5dGUKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zaGxfcm91dGVAMzI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NobAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc2hyX3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NAogICAgLy8gY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaHIKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3NxcnRfcm91dGVAMzQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NxcnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3N1YnN0cmluZ19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N1YnN0cmluZwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2pzb25fcmVmX3N0cmluZ19yb3V0ZUAzNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9qc29uX3JlZl9zdHJpbmcKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9qc29uX3JlZl91aW50NjRfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfanNvbl9yZWZfdWludDY0CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9qc29uX3JlZl9vYmplY3Rfcm91dGVAMzg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxOTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTkxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfanNvbl9yZWZfb2JqZWN0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdANDE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0CiAgICAvLyBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2FkZHcoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfYWRkdzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjUtNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWRkdyhzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gdHVwbGVbVUludDY0LCBVSW50NjRdOgogICAgcHJvdG8gMiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo3CiAgICAvLyByZXN1bHQgPSBvcC5hZGR3KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYWRkdwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6OAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMC0xMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZChzZWxmLCBhOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEyCiAgICAvLyByZXN1bHQgPSBvcC5iYXNlNjRfZGVjb2RlKG9wLkJhc2U2NC5TdGRFbmNvZGluZywgYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYmFzZTY0X2RlY29kZSBTdGRFbmNvZGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfYmFzZTY0X2RlY29kZV91cmwoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmFzZTY0X2RlY29kZV91cmw6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNS0xNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmFzZTY0X2RlY29kZV91cmwoc2VsZiwgYTogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNwogICAgLy8gcmVzdWx0ID0gb3AuYmFzZTY0X2RlY29kZShvcC5CYXNlNjQuVVJMRW5jb2RpbmcsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhc2U2NF9kZWNvZGUgVVJMRW5jb2RpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE4CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2JpdGxlbihhOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlc19iaXRsZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToyMC0yMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnl0ZXNfYml0bGVuKHNlbGYsIGE6IEJ5dGVzLCBwYWRfYV9zaXplOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MjIKICAgIC8vIGEgPSBvcC5iemVybyhwYWRfYV9zaXplKSArIGEKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgLTIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjIzCiAgICAvLyByZXN1bHQgPSBvcC5iaXRsZW4oYSkKICAgIGJpdGxlbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2JpdGxlbihhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9iaXRsZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToyNi0yNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2JpdGxlbihzZWxmLCBhOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MjgKICAgIC8vIHJlc3VsdCA9IG9wLmJpdGxlbihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiaXRsZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjI5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2JzcXJ0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JzcXJ0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MzEtMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JzcXJ0KHNlbGYsIGE6IEJ5dGVzKSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MzQKICAgIC8vIHJlc3VsdCA9IG9wLmJzcXJ0KGFfYmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgYnNxcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjM1CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J0b2koYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J0b2k6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTozNy0zOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnRvaShzZWxmLCBhOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTozOQogICAgLy8gcmVzdWx0ID0gb3AuYnRvaShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0MAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iemVybyhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYnplcm86CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0Mi00MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnplcm8oc2VsZiwgYTogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NDQKICAgIC8vIHJlc3VsdCA9IG9wLmJ6ZXJvKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo0NQogICAgLy8gcmV0dXJuIG9wLnNoYTI1NihyZXN1bHQpCiAgICBzaGEyNTYKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfY29uY2F0KGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfY29uY2F0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NDctNDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2NvbmNhdChzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMsIHBhZF9hX3NpemU6IFVJbnQ2NCwgcGFkX2Jfc2l6ZTogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDQgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NDkKICAgIC8vIGEgPSBvcC5iemVybyhwYWRfYV9zaXplKSArIGEKICAgIGZyYW1lX2RpZyAtMgogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtNAogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IC00CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo1MAogICAgLy8gYiA9IG9wLmJ6ZXJvKHBhZF9iX3NpemUpICsgYgogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIGZyYW1lX2J1cnkgLTMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjUxCiAgICAvLyByZXN1bHQgPSBhICsgYgogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NTIKICAgIC8vIHJlc3VsdCA9IG9wLnNoYTI1NihyZXN1bHQpCiAgICBzaGEyNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjUzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2Rpdm1vZHcoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCwgZDogdWludDY0KSAtPiB1aW50NjQsIHVpbnQ2NCwgdWludDY0LCB1aW50NjQ6CnZlcmlmeV9kaXZtb2R3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NTUtNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Rpdm1vZHcoCiAgICAvLyAgICAgc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQsIGM6IFVJbnQ2NCwgZDogVUludDY0CiAgICAvLyApIC0+IHR1cGxlW1VJbnQ2NCwgVUludDY0LCBVSW50NjQsIFVJbnQ2NF06CiAgICBwcm90byA0IDQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjU5CiAgICAvLyByZXN1bHQgPSBvcC5kaXZtb2R3KGEsIGIsIGMsIGQpCiAgICBmcmFtZV9kaWcgLTQKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGRpdm1vZHcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjYwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2RpdncoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZGl2dzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjYyLTYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9kaXZ3KHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0LCBjOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NjQKICAgIC8vIHJlc3VsdCA9IG9wLmRpdncoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGRpdncKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjY1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2VycigpIC0+IHZvaWQ6CnZlcmlmeV9lcnI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo2Ny02OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZXJyKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjY5CiAgICAvLyBvcC5lcnIoKQogICAgZXJyCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHAoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2V4cDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjcxLTcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9leHAoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzMKICAgIC8vIHJlc3VsdCA9IG9wLmV4cChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4cAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXhwdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQ6CnZlcmlmeV9leHB3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzYtNzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2V4cHcoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IHR1cGxlW1VJbnQ2NCwgVUludDY0XToKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6NzgKICAgIC8vIHJlc3VsdCA9IG9wLmV4cHcoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHB3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo3OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0KGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9leHRyYWN0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6ODEtODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2V4dHJhY3Qoc2VsZiwgYTogQnl0ZXMsIGI6IFVJbnQ2NCwgYzogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6ODMKICAgIC8vIHJlc3VsdCA9IG9wLmV4dHJhY3QoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo4NAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X2Zyb21fMihhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9leHRyYWN0X2Zyb21fMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5Ojg2LTg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9leHRyYWN0X2Zyb21fMihzZWxmLCBhOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5Ojg4CiAgICAvLyByZXN1bHQgPSBvcC5leHRyYWN0KGEsIDIsIDApCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo4OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQxNihhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjkxLTkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9leHRyYWN0X3VpbnQxNihzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjkzCiAgICAvLyByZXN1bHQgPSBvcC5leHRyYWN0X3VpbnQxNihhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3RfdWludDE2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo5NAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQzMihhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5Ojk2LTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9leHRyYWN0X3VpbnQzMihzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5Ojk4CiAgICAvLyByZXN1bHQgPSBvcC5leHRyYWN0X3VpbnQzMihhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3RfdWludDMyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weTo5OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwMS0xMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2V4dHJhY3RfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTAzCiAgICAvLyByZXN1bHQgPSBvcC5leHRyYWN0X3VpbnQ2NChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3RfdWludDY0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMDQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZ2V0Yml0X2J5dGVzKGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldGJpdF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwNi0xMDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2dldGJpdF9ieXRlcyhzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEwOAogICAgLy8gcmVzdWx0ID0gb3AuZ2V0Yml0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZ2V0Yml0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMDkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZ2V0Yml0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0Yml0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjExMS0xMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2dldGJpdF91aW50NjQoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTEzCiAgICAvLyByZXN1bHQgPSBvcC5nZXRiaXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBnZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjExNAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9nZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldGJ5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMTYtMTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRieXRlKHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTE4CiAgICAvLyByZXN1bHQgPSBvcC5nZXRieXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZ2V0Ynl0ZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTE5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2l0b2IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2l0b2I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMjEtMTIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9pdG9iKHNlbGYsIGE6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEyMwogICAgLy8gcmVzdWx0ID0gb3AuaXRvYihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMjQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfbXVsdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQ6CnZlcmlmeV9tdWx3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTI2LTEyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfbXVsdyhzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gdHVwbGVbVUludDY0LCBVSW50NjRdOgogICAgcHJvdG8gMiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMjgKICAgIC8vIHJlc3VsdCA9IG9wLm11bHcoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBtdWx3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxMjkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfcmVwbGFjZShhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9yZXBsYWNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTMxLTEzMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfcmVwbGFjZShzZWxmLCBhOiBCeXRlcywgYjogVUludDY0LCBjOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEzMwogICAgLy8gcmVzdWx0ID0gb3AucmVwbGFjZShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgcmVwbGFjZTMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjEzNAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZWxlY3RfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc2VsZWN0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTM2LTEzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2VsZWN0X2J5dGVzKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgYzogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTM4CiAgICAvLyByZXN1bHQgPSBvcC5zZWxlY3RfYnl0ZXMoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNlbGVjdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTM5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NlbGVjdF91aW50NjQoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc2VsZWN0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE0MS0xNDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3NlbGVjdF91aW50NjQoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQsIGM6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNDMKICAgIC8vIHJlc3VsdCA9IG9wLnNlbGVjdF91aW50NjQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNlbGVjdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTQ0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NldGJpdF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc2V0Yml0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTQ2LTE0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2V0Yml0X2J5dGVzKHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQsIGM6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE0OAogICAgLy8gcmVzdWx0ID0gb3Auc2V0Yml0X2J5dGVzKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE0OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NldGJpdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNTEtMTUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9zZXRiaXRfdWludDY0KHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0LCBjOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyByZXN1bHQgPSBvcC5zZXRiaXRfdWludDY0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1NAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zZXRieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTU2LTE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2V0Ynl0ZShzZWxmLCBhOiBCeXRlcywgYjogVUludDY0LCBjOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNTgKICAgIC8vIHJlc3VsdCA9IG9wLnNldGJ5dGUoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNldGJ5dGUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE1OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLk1pc2NlbGxhbmVvdXNPcHMuY29udHJhY3QuTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zaGwoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NobDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE2MS0xNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3NobChzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNjMKICAgIC8vIHJlc3VsdCA9IG9wLnNobChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNobAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTY0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NocihhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc2hyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTY2LTE2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc2hyKHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE2OAogICAgLy8gcmVzdWx0ID0gb3Auc2hyKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2hyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNjkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc3FydChhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NxcnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNzEtMTcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9zcXJ0KHNlbGYsIGE6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNzMKICAgIC8vIHJlc3VsdCA9IG9wLnNxcnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgc3FydAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTc0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3N1YnN0cmluZyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc3Vic3RyaW5nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTc2LTE3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfc3Vic3RyaW5nKHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQsIGM6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE3OAogICAgLy8gcmVzdWx0ID0gb3Auc3Vic3RyaW5nKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzdWJzdHJpbmczCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxNzkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5NaXNjZWxsYW5lb3VzT3BzLmNvbnRyYWN0Lk1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfanNvbl9yZWZfc3RyaW5nKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9qc29uX3JlZl9zdHJpbmc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvTWlzY2VsbGFuZW91c09wcy9jb250cmFjdC5weToxODEtMTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9qc29uX3JlZl9zdHJpbmcoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTgzCiAgICAvLyByZXN1bHQgPSBvcC5Kc29uUmVmLmpzb25fc3RyaW5nKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAganNvbl9yZWYgSlNPTlN0cmluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTg0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2pzb25fcmVmX3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2pzb25fcmVmX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE4Ni0xODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2pzb25fcmVmX3VpbnQ2NChzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTg4CiAgICAvLyByZXN1bHQgPSBvcC5Kc29uUmVmLmpzb25fdWludDY0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAganNvbl9yZWYgSlNPTlVpbnQ2NAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTg5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2pzb25fcmVmX29iamVjdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfanNvbl9yZWZfb2JqZWN0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL01pc2NlbGxhbmVvdXNPcHMvY29udHJhY3QucHk6MTkxLTE5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfanNvbl9yZWZfb2JqZWN0KHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE5MwogICAgLy8gcmVzdWx0ID0gb3AuSnNvblJlZi5qc29uX29iamVjdChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGpzb25fcmVmIEpTT05PYmplY3QKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjE5NAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuTWlzY2VsbGFuZW91c09wcy5jb250cmFjdC5NaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9NaXNjZWxsYW5lb3VzT3BzL2NvbnRyYWN0LnB5OjQKICAgIC8vIGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" - }, - "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_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[]" - } - }, - { - "name": "verify_json_ref_string", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - }, - { - "name": "verify_json_ref_uint64", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "uint64" - } - }, - { - "name": "verify_json_ref_object", - "args": [ - { - "type": "byte[]", - "name": "a" - }, - { - "type": "byte[]", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "byte[]" - } - } - ], - "networks": {} - }, - "bare_call_config": { - "no_op": "CREATE" + "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_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" + } } -} \ No newline at end of file + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMzgKICAgIHB1c2hieXRlc3MgMHg0NTg0N2VlYSAweGY1N2FjZWI1IDB4N2Q2MzE3MzAgMHhhMWIyNDQ0MSAweGNkN2JlMWFjIDB4N2NmZGE2NGIgMHg1NGE5MTBkOSAweGM0NjU2OGRlIDB4N2E0NmE2YWUgMHgwNDM3MjIwOSAweDdlNWY2ZDcyIDB4MjRlYmNmODQgMHg5YzBiMzM5NyAweDBhZDQwZGE0IDB4OTUxNzg4NzAgMHhkZWVkYzk5YiAweGFiMjE1MGJiIDB4MDJhNTQwMTcgMHgzZGI2NmI0MSAweGM3ZWE4YzJhIDB4MWRjZWE1MGMgMHgxNjE2NmY5YSAweDJmNDcyMDY1IDB4ZDVhNzM5YzMgMHg2MWYzYjNlMSAweDU2Y2YzNjhiIDB4OTE5ZmZiZDIgMHg4ZTMwZjRlNyAweDg5ZjgxZDkyIDB4ZDUyNjAzMjcgMHgxMTRjOGM2ZCAweDM5ZTllNjJhIDB4ZDZhNGMwNWUgMHgxZWY4MTUxYSAvLyBtZXRob2QgInZlcmlmeV9hZGR3KHVpbnQ2NCx1aW50NjQpKHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZChieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmFzZTY0X2RlY29kZV91cmwoYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX2JpdGxlbihieXRlW10sdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9iaXRsZW4odWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2JzcXJ0KGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9idG9pKGJ5dGVbXSl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9iemVybyh1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfY29uY2F0KGJ5dGVbXSxieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9kaXZtb2R3KHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCkodWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0KSIsIG1ldGhvZCAidmVyaWZ5X2RpdncodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZXJyKCl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfZXhwKHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZXhwdyh1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0KSIsIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3QoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF9mcm9tXzIoYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3RfdWludDE2KGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF91aW50MzIoYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9leHRyYWN0X3VpbnQ2NChieXRlW10sdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2dldGJpdF9ieXRlcyhieXRlW10sdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2dldGJpdF91aW50NjQodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9nZXRieXRlKGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfaXRvYih1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfbXVsdyh1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0KSIsIG1ldGhvZCAidmVyaWZ5X3JlcGxhY2UoYnl0ZVtdLHVpbnQ2NCxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2VsZWN0X2J5dGVzKGJ5dGVbXSxieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3NlbGVjdF91aW50NjQodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfc2V0Yml0X2J5dGVzKGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3NldGJpdF91aW50NjQodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfc2V0Ynl0ZShieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9zaGwodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zaHIodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zcXJ0KHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zdWJzdHJpbmcoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FkZHdfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZF9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybF9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19iaXRsZW5fcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2JpdGxlbl9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ic3FydF9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9idG9pX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J6ZXJvX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2NvbmNhdF9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZGl2bW9kd19yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZGl2d19yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXJyX3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHBfcm91dGVAMTQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4cHdfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3Rfcm91dGVAMTYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfZnJvbV8yX3JvdXRlQDE3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHRyYWN0X3VpbnQxNl9yb3V0ZUAxOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF91aW50MzJfcm91dGVAMTkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfdWludDY0X3JvdXRlQDIwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRiaXRfYnl0ZXNfcm91dGVAMjEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF91aW50NjRfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJ5dGVfcm91dGVAMjMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2l0b2Jfcm91dGVAMjQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X211bHdfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3JlcGxhY2Vfcm91dGVAMjYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF9ieXRlc19yb3V0ZUAyNyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2VsZWN0X3VpbnQ2NF9yb3V0ZUAyOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Yml0X2J5dGVzX3JvdXRlQDI5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZXRiaXRfdWludDY0X3JvdXRlQDMwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZXRieXRlX3JvdXRlQDMxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaGxfcm91dGVAMzIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3Nocl9yb3V0ZUAzMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3FydF9yb3V0ZUAzNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3Vic3RyaW5nX3JvdXRlQDM1CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWRkd19yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hZGR3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmFzZTY0X2RlY29kZV91cmxfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmFzZTY0X2RlY29kZV91cmwKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfYml0bGVuX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2JpdGxlbgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9iaXRsZW5fcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfYml0bGVuCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnNxcnRfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnNxcnQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnRvaV9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9idG9pCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnplcm9fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iemVybwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9jb25jYXRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9jb25jYXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZGl2bW9kd19yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9kaXZtb2R3CiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIHVuY292ZXIgMwogICAgaXRvYgogICAgdW5jb3ZlciAzCiAgICBpdG9iCiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAzCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZ3X3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2RpdncKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lcnJfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgdmVyaWZ5X2VycgogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4cF9yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHAKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHB3X3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4cHcKICAgIHN3YXAKICAgIGl0b2IKICAgIHN3YXAKICAgIGl0b2IKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3Rfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3QKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9mcm9tXzJfcm91dGVAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfZnJvbV8yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfdWludDE2X3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfdWludDE2CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF91aW50MzJfcm91dGVAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXh0cmFjdF91aW50MzIKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHRyYWN0X3VpbnQ2NF9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHRyYWN0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF9ieXRlc19yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRiaXRfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRiaXRfdWludDY0X3JvdXRlQDIyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0Yml0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJ5dGVfcm91dGVAMjM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0Ynl0ZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2l0b2Jfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9pdG9iCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X211bHdfcm91dGVAMjU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9tdWx3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9yZXBsYWNlX3JvdXRlQDI2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9yZXBsYWNlCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF9ieXRlc19yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2VsZWN0X2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF91aW50NjRfcm91dGVAMjg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zZWxlY3RfdWludDY0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Yml0X2J5dGVzX3JvdXRlQDI5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NldGJpdF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZXRiaXRfdWludDY0X3JvdXRlQDMwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2V0Yml0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NldGJ5dGVfcm91dGVAMzE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2V0Ynl0ZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaGxfcm91dGVAMzI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaHJfcm91dGVAMzM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaHIKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zcXJ0X3JvdXRlQDM0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc3FydAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N1YnN0cmluZ19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdWJzdHJpbmcKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMzg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA0MgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA0MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9hZGR3KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQsIHVpbnQ2NDoKdmVyaWZ5X2FkZHc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0LTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FkZHcoYTogdWludDY0LCBiOiB1aW50NjQpOiByZWFkb25seSBbdWludDY0LCB1aW50NjRdIHsKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NgogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYWRkdyhhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFkZHcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwLTExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkKGE6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMgogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYmFzZTY0RGVjb2RlKEJhc2U2NC5TdGRFbmNvZGluZywgYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYmFzZTY0X2RlY29kZSBTdGRFbmNvZGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYtMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsKGE6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYmFzZTY0RGVjb2RlKEJhc2U2NC5VUkxFbmNvZGluZywgYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYmFzZTY0X2RlY29kZSBVUkxFbmNvZGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2JpdGxlbihhOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlc19iaXRsZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMi0yMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfYml0bGVuKGE6IGJ5dGVzLCBwYWRfYV9zaXplOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyNAogICAgLy8gY29uc3QgcGFkZGVkQSA9IG9wLmJ6ZXJvKHBhZF9hX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5iaXRMZW5ndGgocGFkZGVkQSkKICAgIGJpdGxlbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9iaXRsZW4oYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfYml0bGVuOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjktMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9iaXRsZW4oYTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJpdExlbmd0aChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiaXRsZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9ic3FydChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ic3FydDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1LTM2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ic3FydChhOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJzcXJ0KGFfYmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgYnNxcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5CiAgICAvLyByZXR1cm4gQnl0ZXMocmVzdWx0KQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfYnRvaShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnRvaToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyLTQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9idG9pKGE6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJ0b2koYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J6ZXJvKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iemVybzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4LTQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iemVybyhhOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5iemVybyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIHJldHVybiBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9jb25jYXQoYTogYnl0ZXMsIGI6IGJ5dGVzLCBwYWRfYV9zaXplOiB1aW50NjQsIHBhZF9iX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9jb25jYXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1NC01NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfY29uY2F0KGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byA0IDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU2CiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX2Ffc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTcKICAgIC8vIGNvbnN0IHBhZGRlZEIgPSBvcC5iemVybyhwYWRfYl9zaXplKS5jb25jYXQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1OAogICAgLy8gY29uc3QgcmVzdWx0ID0gcGFkZGVkQS5jb25jYXQocGFkZGVkQikKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkKICAgIC8vIGNvbnN0IHJlc3VsdEhhc2ggPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2MAogICAgLy8gcmV0dXJuIHJlc3VsdEhhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2Rpdm1vZHcoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCwgZDogdWludDY0KSAtPiB1aW50NjQsIHVpbnQ2NCwgdWludDY0LCB1aW50NjQ6CnZlcmlmeV9kaXZtb2R3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMtNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Rpdm1vZHcoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCwgZDogdWludDY0KTogcmVhZG9ubHkgW3VpbnQ2NCwgdWludDY0LCB1aW50NjQsIHVpbnQ2NF0gewogICAgcHJvdG8gNCA0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZGl2bW9kdyhhLCBiLCBjLCBkKQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBkaXZtb2R3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2NgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZGl2dyhhOiB1aW50NjQsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9kaXZ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjktNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2RpdncoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5kaXZ3KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBkaXZ3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3MgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXJyKCkgLT4gdm9pZDoKdmVyaWZ5X2VycjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1LTc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9lcnIoKTogdm9pZCB7CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3CiAgICAvLyBlcnIoKQogICAgZXJyCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXhwKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4MC04MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXhwKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmV4cChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4cAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4cHcoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfZXhwdzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2LTg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9leHB3KGE6IHVpbnQ2NCwgYjogdWludDY0KTogcmVhZG9ubHkgW3VpbnQ2NCwgdWludDY0XSB7CiAgICBwcm90byAyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjg4CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHB3KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXhwdwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4dHJhY3QoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2V4dHJhY3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5Mi05MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXh0cmFjdChhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjk0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHRyYWN0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0MwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4dHJhY3RfZnJvbV8yKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2V4dHJhY3RfZnJvbV8yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTgtOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3RfZnJvbV8yKGE6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMDAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmV4dHJhY3QoYSwgMiwgMCkKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXh0cmFjdF91aW50MTYoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZXh0cmFjdF91aW50MTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMDQtMTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9leHRyYWN0X3VpbnQxNihhOiBieXRlcywgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA2CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHRyYWN0VWludDE2KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdF91aW50MTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXh0cmFjdF91aW50MzIoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZXh0cmFjdF91aW50MzI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTAtMTExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9leHRyYWN0X3VpbnQzMihhOiBieXRlcywgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHRyYWN0VWludDMyKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdF91aW50MzIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXh0cmFjdF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZXh0cmFjdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTYtMTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9leHRyYWN0X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE4CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHRyYWN0VWludDY0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdF91aW50NjQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExOQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZ2V0Yml0X2J5dGVzKGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldGJpdF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMi0xMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2dldGJpdF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5nZXRCaXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBnZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZ2V0Yml0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0Yml0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOC0xMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2dldGJpdF91aW50NjQoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmdldEJpdChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGdldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9nZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldGJ5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzQtMTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9nZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmdldEJ5dGUoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBnZXRieXRlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2l0b2IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2l0b2I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDAtMTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9pdG9iKGE6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5pdG9iKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfbXVsdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQ6CnZlcmlmeV9tdWx3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ2LTE0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfbXVsdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHJlYWRvbmx5IFt1aW50NjQsIHVpbnQ2NF0gewogICAgcHJvdG8gMiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLm11bHcoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBtdWx3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3JlcGxhY2UoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfcmVwbGFjZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1Mi0xNTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3JlcGxhY2UoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AucmVwbGFjZShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgcmVwbGFjZTMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc2VsZWN0X2J5dGVzKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NlbGVjdF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1OC0xNTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NlbGVjdF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYwCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZWxlY3QoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNlbGVjdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZWxlY3RfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NlbGVjdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjQtMTY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZWxlY3RfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNlbGVjdChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2VsZWN0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NldGJpdF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc2V0Yml0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcwLTE3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2V0Yml0X2J5dGVzKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZXRCaXQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NldGJpdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNzYtMTc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNzgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNldEJpdChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2V0Yml0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNzkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NldGJ5dGUoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NldGJ5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODItMTgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZXRCeXRlKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZXRieXRlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NobChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc2hsOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg4LTE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2hsKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkwCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zaGwoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaGwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc2hyKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9zaHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTQtMTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zaHIoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNocihhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNocgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zcXJ0KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc3FydDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMC0yMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NxcnQoYTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zcXJ0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHNxcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc3Vic3RyaW5nKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zdWJzdHJpbmc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDYtMjA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdWJzdHJpbmcoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnN1YnN0cmluZyhhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc3Vic3RyaW5nMwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIK=", + "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_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.clear.teal b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.clear.teal index 69f45be..ccc2a5e 100644 --- a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.clear.teal +++ b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.MiscellaneousOps.contract.MiscellaneousOpsContract.clear_state_program: - // tests/artifacts/MiscellaneousOps/contract.py:4 - // class MiscellaneousOpsContract(ARC4Contract): - int 1 +tests/artifacts/miscellaneous-ops/contract.algo.ts::MiscellaneousOpsContract.clearStateProgram: + pushint 1 // 1 return diff --git a/tests/artifacts/primitive-ops/contract.algo.ts b/tests/artifacts/primitive-ops/contract.algo.ts new file mode 100644 index 0000000..0ea7097 --- /dev/null +++ b/tests/artifacts/primitive-ops/contract.algo.ts @@ -0,0 +1,416 @@ +import { arc4, biguint, BigUint, Bytes, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' + +export class PrimitiveOpsContract extends arc4.Contract { + @arc4.abimethod() + public verify_uint64_init(raw_value: bytes): uint64 { + const result = op.btoi(raw_value) + return result + } + + @arc4.abimethod() + public verify_uint64_add(a: uint64, b: uint64): uint64 { + const result: uint64 = a + b + return result + } + + @arc4.abimethod() + public verify_uint64_sub(a: uint64, b: uint64): uint64 { + const result: uint64 = a - b + return result + } + + @arc4.abimethod() + public verify_uint64_mul(a: uint64, b: uint64): uint64 { + const result: uint64 = a * b + return result + } + + @arc4.abimethod() + public verify_uint64_div(a: uint64, b: uint64): uint64 { + const result: uint64 = a / b + return result + } + + @arc4.abimethod() + public verify_uint64_mod(a: uint64, b: uint64): uint64 { + const result: uint64 = a % b + return result + } + + @arc4.abimethod() + public verify_uint64_and(a: uint64, b: uint64): uint64 { + const result: uint64 = a & b + return result + } + + @arc4.abimethod() + public verify_uint64_or(a: uint64, b: uint64): uint64 { + const result: uint64 = a | b + return result + } + + @arc4.abimethod() + public verify_uint64_xor(a: uint64, b: uint64): uint64 { + const result: uint64 = a ^ b + return result + } + + @arc4.abimethod() + public verify_uint64_not(a: uint64): uint64 { + const result: uint64 = ~a + return result + } + + @arc4.abimethod() + public verify_uint64_lshift(a: uint64, b: uint64): uint64 { + const result: uint64 = a << b + return result + } + + @arc4.abimethod() + public verify_uint64_rshift(a: uint64, b: uint64): uint64 { + const result: uint64 = a >> b + return result + } + + @arc4.abimethod() + public verify_uint64_pow(a: uint64, b: uint64): uint64 { + const result: uint64 = a ** b + return result + } + + @arc4.abimethod() + public verify_uint64_eq(a: uint64, b: uint64): boolean { + const result = a === b + return result + } + + @arc4.abimethod() + public verify_uint64_ne(a: uint64, b: uint64): boolean { + const result = a !== b + return result + } + + @arc4.abimethod() + public verify_uint64_lt(a: uint64, b: uint64): boolean { + const result = a < b + return result + } + + @arc4.abimethod() + public verify_uint64_le(a: uint64, b: uint64): boolean { + const result = a <= b + return result + } + + @arc4.abimethod() + public verify_uint64_gt(a: uint64, b: uint64): boolean { + const result = a > b + return result + } + + @arc4.abimethod() + public verify_uint64_ge(a: uint64, b: uint64): boolean { + const result = a >= b + return result + } + + @arc4.abimethod() + public verify_bytes_init(raw_value: uint64): bytes { + const result = op.itob(raw_value) + return result + } + + @arc4.abimethod() + public verify_bytes_add(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64): bytes { + const paddedA = op.bzero(pad_a_size).concat(a) + const paddedB = op.bzero(pad_b_size).concat(b) + const result = paddedA.concat(paddedB) + const resultHash = op.sha256(result) + return resultHash + } + + @arc4.abimethod() + public verify_bytes_eq(a: bytes, b: bytes): boolean { + const result = a === b + return result + } + + @arc4.abimethod() + public verify_bytes_ne(a: bytes, b: bytes): boolean { + const result = a !== b + return result + } + + @arc4.abimethod() + public verify_bytes_and(a: bytes, b: bytes): bytes { + const result = a.bitwiseAnd(b) + return result + } + + @arc4.abimethod() + public verify_bytes_or(a: bytes, b: bytes): bytes { + const result = a.bitwiseOr(b) + return result + } + + @arc4.abimethod() + public verify_bytes_xor(a: bytes, b: bytes): bytes { + const result = a.bitwiseXor(b) + return result + } + + @arc4.abimethod() + public verify_bytes_not(a: bytes, pad_size: uint64): bytes { + const paddedA = op.bzero(pad_size).concat(a) + const result = paddedA.bitwiseInvert() + const resultHash = op.sha256(result) + return resultHash + } + + @arc4.abimethod() + public verify_biguint_add(a: bytes, b: bytes): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint + b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_add_uint64(a: bytes, b: uint64): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint + b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_sub(a: bytes, b: bytes): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint - b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_sub_uint64(a: bytes, b: uint64): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint - b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_mul(a: bytes, b: bytes): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint * b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_mul_uint64(a: bytes, b: uint64): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint * b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_div(a: bytes, b: bytes): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint / b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_div_uint64(a: bytes, b: uint64): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint / b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_mod(a: bytes, b: bytes): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint % b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_mod_uint64(a: bytes, b: uint64): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint % b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_and(a: bytes, b: bytes): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint & b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_and_uint64(a: bytes, b: uint64): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint & b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_or(a: bytes, b: bytes): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint | b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_or_uint64(a: bytes, b: uint64): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint | b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_xor(a: bytes, b: bytes): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint ^ b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_xor_uint64(a: bytes, b: uint64): bytes { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result: biguint = a_biguint ^ b_biguint + return Bytes(result) + } + + @arc4.abimethod() + public verify_biguint_eq(a: bytes, b: bytes): boolean { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result = a_biguint === b_biguint + return result + } + + @arc4.abimethod() + public verify_biguint_eq_uint64(a: bytes, b: uint64): boolean { + const a_biguint = BigUint(a) + const result = a_biguint === BigUint(b) + return result + } + + @arc4.abimethod() + public verify_biguint_ne(a: bytes, b: bytes): boolean { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result = a_biguint !== b_biguint + return result + } + + @arc4.abimethod() + public verify_biguint_ne_uint64(a: bytes, b: uint64): boolean { + const a_biguint = BigUint(a) + const result = a_biguint !== BigUint(b) + return result + } + + @arc4.abimethod() + public verify_biguint_lt(a: bytes, b: bytes): boolean { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result = a_biguint < b_biguint + return result + } + + @arc4.abimethod() + public verify_biguint_lt_uint64(a: bytes, b: uint64): boolean { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result = a_biguint < b_biguint + return result + } + + @arc4.abimethod() + public verify_biguint_le(a: bytes, b: bytes): boolean { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result = a_biguint <= b_biguint + return result + } + + @arc4.abimethod() + public verify_biguint_le_uint64(a: bytes, b: uint64): boolean { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result = a_biguint <= b_biguint + return result + } + + @arc4.abimethod() + public verify_biguint_gt(a: bytes, b: bytes): boolean { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result = a_biguint > b_biguint + return result + } + + @arc4.abimethod() + public verify_biguint_gt_uint64(a: bytes, b: uint64): boolean { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result = a_biguint > b_biguint + return result + } + + @arc4.abimethod() + public verify_biguint_ge(a: bytes, b: bytes): boolean { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result = a_biguint >= b_biguint + return result + } + + @arc4.abimethod() + public verify_biguint_ge_uint64(a: bytes, b: uint64): boolean { + const a_biguint = BigUint(a) + const b_biguint = BigUint(b) + const result = a_biguint >= b_biguint + return result + } + + // TODO: uncomment when arc4 types are available + // @arc4.abimethod + // public verify_log( # noqa: PLR0913 + // self, + // a: String, + // b: uint64, + // c: bytes, + // d: bytes, + // e: arc4.boolean, + // f: arc4.String, + // g: arc4.UIntN[typing.Literal[64]], + // h: arc4.BigUIntN[typing.Literal[256]], + // i: arc4.UFixedNxM[typing.Literal[32], typing.Literal[8]], + // j: arc4.BigUFixedNxM[typing.Literal[256], typing.Literal[16]], + // k: bytes, + // m: bytes, + // n: bytes, + // ) : None: + // d_biguint = BigUint(d) + // arc4_k = arc4.StaticArray[arc4.UInt8, typing.Literal[3]].from_bytes(k) + // arc4_m = arc4.DynamicArray[arc4.UInt16].from_bytes(m) + // arc4_n = arc4.Tuple[arc4.UInt32, arc4.uint64, arc4.String].from_bytes(n) + // log(a, b, c, d_biguint, e, f, g, h, i, j, arc4_k, arc4_m, arc4_n, sep="-") +} diff --git a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal index 058b711..4e77e89 100644 --- a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal +++ b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal @@ -1,576 +1,527 @@ #pragma version 10 -tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.approval_program: - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): +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:3 + // export class PrimitiveOpsContract extends arc4.Contract { + proto 0 1 txn NumAppArgs - bz main_bare_routing@64 - 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_string_init(string)string" - method "verify_string_startswith(string,string)bool" - method "verify_string_endswith(string,string)bool" - method "verify_string_join(string,string)string" - method "verify_log(string,uint64,byte[],byte[],bool,string,uint64,uint256,ufixed32x8,ufixed256x16,byte[],byte[],byte[])void" + bz __puya_arc4_router___bare_routing@59 + 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 // 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" txna ApplicationArgs 0 - match main_verify_uint64_init_route@2 main_verify_uint64_add_route@3 main_verify_uint64_sub_route@4 main_verify_uint64_mul_route@5 main_verify_uint64_div_route@6 main_verify_uint64_mod_route@7 main_verify_uint64_and_route@8 main_verify_uint64_or_route@9 main_verify_uint64_xor_route@10 main_verify_uint64_not_route@11 main_verify_uint64_lshift_route@12 main_verify_uint64_rshift_route@13 main_verify_uint64_pow_route@14 main_verify_uint64_eq_route@15 main_verify_uint64_ne_route@16 main_verify_uint64_lt_route@17 main_verify_uint64_le_route@18 main_verify_uint64_gt_route@19 main_verify_uint64_ge_route@20 main_verify_bytes_init_route@21 main_verify_bytes_add_route@22 main_verify_bytes_eq_route@23 main_verify_bytes_ne_route@24 main_verify_bytes_and_route@25 main_verify_bytes_or_route@26 main_verify_bytes_xor_route@27 main_verify_bytes_not_route@28 main_verify_biguint_add_route@29 main_verify_biguint_add_uint64_route@30 main_verify_biguint_sub_route@31 main_verify_biguint_sub_uint64_route@32 main_verify_biguint_mul_route@33 main_verify_biguint_mul_uint64_route@34 main_verify_biguint_div_route@35 main_verify_biguint_div_uint64_route@36 main_verify_biguint_mod_route@37 main_verify_biguint_mod_uint64_route@38 main_verify_biguint_and_route@39 main_verify_biguint_and_uint64_route@40 main_verify_biguint_or_route@41 main_verify_biguint_or_uint64_route@42 main_verify_biguint_xor_route@43 main_verify_biguint_xor_uint64_route@44 main_verify_biguint_eq_route@45 main_verify_biguint_eq_uint64_route@46 main_verify_biguint_ne_route@47 main_verify_biguint_ne_uint64_route@48 main_verify_biguint_lt_route@49 main_verify_biguint_lt_uint64_route@50 main_verify_biguint_le_route@51 main_verify_biguint_le_uint64_route@52 main_verify_biguint_gt_route@53 main_verify_biguint_gt_uint64_route@54 main_verify_biguint_ge_route@55 main_verify_biguint_ge_uint64_route@56 main_verify_string_init_route@57 main_verify_string_startswith_route@58 main_verify_string_endswith_route@59 main_verify_string_join_route@60 main_verify_log_route@61 - err // reject transaction + 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 + intc_1 // 0 + retsub -main_verify_uint64_init_route@2: - // tests/artifacts/PrimitiveOps/contract.py:7 +__puya_arc4_router___verify_uint64_init_route@2: + // tests/artifacts/primitive-ops/contract.algo.ts:4 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:7 + // tests/artifacts/primitive-ops/contract.algo.ts:4 // @arc4.abimethod() callsub verify_uint64_init itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_add_route@3: - // tests/artifacts/PrimitiveOps/contract.py:12 +__puya_arc4_router___verify_uint64_add_route@3: + // tests/artifacts/primitive-ops/contract.algo.ts:10 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:12 + // tests/artifacts/primitive-ops/contract.algo.ts:10 // @arc4.abimethod() callsub verify_uint64_add itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_sub_route@4: - // tests/artifacts/PrimitiveOps/contract.py:17 +__puya_arc4_router___verify_uint64_sub_route@4: + // tests/artifacts/primitive-ops/contract.algo.ts:16 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:17 + // tests/artifacts/primitive-ops/contract.algo.ts:16 // @arc4.abimethod() callsub verify_uint64_sub itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_mul_route@5: - // tests/artifacts/PrimitiveOps/contract.py:22 +__puya_arc4_router___verify_uint64_mul_route@5: + // tests/artifacts/primitive-ops/contract.algo.ts:22 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:22 + // tests/artifacts/primitive-ops/contract.algo.ts:22 // @arc4.abimethod() callsub verify_uint64_mul itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_div_route@6: - // tests/artifacts/PrimitiveOps/contract.py:27 +__puya_arc4_router___verify_uint64_div_route@6: + // tests/artifacts/primitive-ops/contract.algo.ts:28 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:27 + // tests/artifacts/primitive-ops/contract.algo.ts:28 // @arc4.abimethod() callsub verify_uint64_div itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_mod_route@7: - // tests/artifacts/PrimitiveOps/contract.py:32 +__puya_arc4_router___verify_uint64_mod_route@7: + // tests/artifacts/primitive-ops/contract.algo.ts:34 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:32 + // tests/artifacts/primitive-ops/contract.algo.ts:34 // @arc4.abimethod() callsub verify_uint64_mod itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_and_route@8: - // tests/artifacts/PrimitiveOps/contract.py:37 +__puya_arc4_router___verify_uint64_and_route@8: + // tests/artifacts/primitive-ops/contract.algo.ts:40 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:37 + // tests/artifacts/primitive-ops/contract.algo.ts:40 // @arc4.abimethod() callsub verify_uint64_and itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_or_route@9: - // tests/artifacts/PrimitiveOps/contract.py:42 +__puya_arc4_router___verify_uint64_or_route@9: + // tests/artifacts/primitive-ops/contract.algo.ts:46 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:42 + // tests/artifacts/primitive-ops/contract.algo.ts:46 // @arc4.abimethod() callsub verify_uint64_or itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_xor_route@10: - // tests/artifacts/PrimitiveOps/contract.py:47 +__puya_arc4_router___verify_uint64_xor_route@10: + // tests/artifacts/primitive-ops/contract.algo.ts:52 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:47 + // tests/artifacts/primitive-ops/contract.algo.ts:52 // @arc4.abimethod() callsub verify_uint64_xor itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_not_route@11: - // tests/artifacts/PrimitiveOps/contract.py:52 +__puya_arc4_router___verify_uint64_not_route@11: + // tests/artifacts/primitive-ops/contract.algo.ts:58 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi - // tests/artifacts/PrimitiveOps/contract.py:52 + // tests/artifacts/primitive-ops/contract.algo.ts:58 // @arc4.abimethod() callsub verify_uint64_not itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_lshift_route@12: - // tests/artifacts/PrimitiveOps/contract.py:57 +__puya_arc4_router___verify_uint64_lshift_route@12: + // tests/artifacts/primitive-ops/contract.algo.ts:64 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:57 + // tests/artifacts/primitive-ops/contract.algo.ts:64 // @arc4.abimethod() callsub verify_uint64_lshift itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_rshift_route@13: - // tests/artifacts/PrimitiveOps/contract.py:62 +__puya_arc4_router___verify_uint64_rshift_route@13: + // tests/artifacts/primitive-ops/contract.algo.ts:70 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:62 + // tests/artifacts/primitive-ops/contract.algo.ts:70 // @arc4.abimethod() callsub verify_uint64_rshift itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_pow_route@14: - // tests/artifacts/PrimitiveOps/contract.py:67 +__puya_arc4_router___verify_uint64_pow_route@14: + // tests/artifacts/primitive-ops/contract.algo.ts:76 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:67 + // tests/artifacts/primitive-ops/contract.algo.ts:76 // @arc4.abimethod() callsub verify_uint64_pow itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_eq_route@15: - // tests/artifacts/PrimitiveOps/contract.py:72 +__puya_arc4_router___verify_uint64_eq_route@15: + // tests/artifacts/primitive-ops/contract.algo.ts:82 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:72 + // tests/artifacts/primitive-ops/contract.algo.ts:82 // @arc4.abimethod() callsub verify_uint64_eq - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_ne_route@16: - // tests/artifacts/PrimitiveOps/contract.py:77 +__puya_arc4_router___verify_uint64_ne_route@16: + // tests/artifacts/primitive-ops/contract.algo.ts:88 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:77 + // tests/artifacts/primitive-ops/contract.algo.ts:88 // @arc4.abimethod() callsub verify_uint64_ne - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_lt_route@17: - // tests/artifacts/PrimitiveOps/contract.py:82 +__puya_arc4_router___verify_uint64_lt_route@17: + // tests/artifacts/primitive-ops/contract.algo.ts:94 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:82 + // tests/artifacts/primitive-ops/contract.algo.ts:94 // @arc4.abimethod() callsub verify_uint64_lt - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_le_route@18: - // tests/artifacts/PrimitiveOps/contract.py:87 +__puya_arc4_router___verify_uint64_le_route@18: + // tests/artifacts/primitive-ops/contract.algo.ts:100 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:87 + // tests/artifacts/primitive-ops/contract.algo.ts:100 // @arc4.abimethod() callsub verify_uint64_le - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_gt_route@19: - // tests/artifacts/PrimitiveOps/contract.py:92 +__puya_arc4_router___verify_uint64_gt_route@19: + // tests/artifacts/primitive-ops/contract.algo.ts:106 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:92 + // tests/artifacts/primitive-ops/contract.algo.ts:106 // @arc4.abimethod() callsub verify_uint64_gt - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_uint64_ge_route@20: - // tests/artifacts/PrimitiveOps/contract.py:97 +__puya_arc4_router___verify_uint64_ge_route@20: + // tests/artifacts/primitive-ops/contract.algo.ts:112 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:97 + // tests/artifacts/primitive-ops/contract.algo.ts:112 // @arc4.abimethod() callsub verify_uint64_ge - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bytes_init_route@21: - // tests/artifacts/PrimitiveOps/contract.py:102 +__puya_arc4_router___verify_bytes_init_route@21: + // tests/artifacts/primitive-ops/contract.algo.ts:118 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 btoi - // tests/artifacts/PrimitiveOps/contract.py:102 + // tests/artifacts/primitive-ops/contract.algo.ts:118 // @arc4.abimethod() callsub verify_bytes_init dup @@ -579,23 +530,23 @@ main_verify_bytes_init_route@21: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bytes_add_route@22: - // tests/artifacts/PrimitiveOps/contract.py:107 +__puya_arc4_router___verify_bytes_add_route@22: + // tests/artifacts/primitive-ops/contract.algo.ts:124 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 @@ -604,7 +555,7 @@ main_verify_bytes_add_route@22: btoi txna ApplicationArgs 4 btoi - // tests/artifacts/PrimitiveOps/contract.py:107 + // tests/artifacts/primitive-ops/contract.algo.ts:124 // @arc4.abimethod() callsub verify_bytes_add dup @@ -613,84 +564,84 @@ main_verify_bytes_add_route@22: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bytes_eq_route@23: - // tests/artifacts/PrimitiveOps/contract.py:117 +__puya_arc4_router___verify_bytes_eq_route@23: + // tests/artifacts/primitive-ops/contract.algo.ts:133 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:117 + // tests/artifacts/primitive-ops/contract.algo.ts:133 // @arc4.abimethod() callsub verify_bytes_eq - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bytes_ne_route@24: - // tests/artifacts/PrimitiveOps/contract.py:122 +__puya_arc4_router___verify_bytes_ne_route@24: + // tests/artifacts/primitive-ops/contract.algo.ts:139 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:122 + // tests/artifacts/primitive-ops/contract.algo.ts:139 // @arc4.abimethod() callsub verify_bytes_ne - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bytes_and_route@25: - // tests/artifacts/PrimitiveOps/contract.py:127 +__puya_arc4_router___verify_bytes_and_route@25: + // tests/artifacts/primitive-ops/contract.algo.ts:145 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:127 + // tests/artifacts/primitive-ops/contract.algo.ts:145 // @arc4.abimethod() callsub verify_bytes_and dup @@ -699,28 +650,28 @@ main_verify_bytes_and_route@25: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bytes_or_route@26: - // tests/artifacts/PrimitiveOps/contract.py:132 +__puya_arc4_router___verify_bytes_or_route@26: + // tests/artifacts/primitive-ops/contract.algo.ts:151 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:132 + // tests/artifacts/primitive-ops/contract.algo.ts:151 // @arc4.abimethod() callsub verify_bytes_or dup @@ -729,28 +680,28 @@ main_verify_bytes_or_route@26: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bytes_xor_route@27: - // tests/artifacts/PrimitiveOps/contract.py:137 +__puya_arc4_router___verify_bytes_xor_route@27: + // tests/artifacts/primitive-ops/contract.algo.ts:157 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:137 + // tests/artifacts/primitive-ops/contract.algo.ts:157 // @arc4.abimethod() callsub verify_bytes_xor dup @@ -759,28 +710,28 @@ main_verify_bytes_xor_route@27: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_bytes_not_route@28: - // tests/artifacts/PrimitiveOps/contract.py:142 +__puya_arc4_router___verify_bytes_not_route@28: + // tests/artifacts/primitive-ops/contract.algo.ts:163 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:142 + // tests/artifacts/primitive-ops/contract.algo.ts:163 // @arc4.abimethod() callsub verify_bytes_not dup @@ -789,28 +740,28 @@ main_verify_bytes_not_route@28: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_add_route@29: - // tests/artifacts/PrimitiveOps/contract.py:149 +__puya_arc4_router___verify_biguint_add_route@29: + // tests/artifacts/primitive-ops/contract.algo.ts:171 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:149 + // tests/artifacts/primitive-ops/contract.algo.ts:171 // @arc4.abimethod() callsub verify_biguint_add dup @@ -819,28 +770,28 @@ main_verify_biguint_add_route@29: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_add_uint64_route@30: - // tests/artifacts/PrimitiveOps/contract.py:156 +__puya_arc4_router___verify_biguint_add_uint64_route@30: + // tests/artifacts/primitive-ops/contract.algo.ts:179 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:156 + // tests/artifacts/primitive-ops/contract.algo.ts:179 // @arc4.abimethod() callsub verify_biguint_add_uint64 dup @@ -849,28 +800,28 @@ main_verify_biguint_add_uint64_route@30: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_sub_route@31: - // tests/artifacts/PrimitiveOps/contract.py:162 +__puya_arc4_router___verify_biguint_sub_route@31: + // tests/artifacts/primitive-ops/contract.algo.ts:187 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:162 + // tests/artifacts/primitive-ops/contract.algo.ts:187 // @arc4.abimethod() callsub verify_biguint_sub dup @@ -879,28 +830,28 @@ main_verify_biguint_sub_route@31: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_sub_uint64_route@32: - // tests/artifacts/PrimitiveOps/contract.py:169 +__puya_arc4_router___verify_biguint_sub_uint64_route@32: + // tests/artifacts/primitive-ops/contract.algo.ts:195 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:169 + // tests/artifacts/primitive-ops/contract.algo.ts:195 // @arc4.abimethod() callsub verify_biguint_sub_uint64 dup @@ -909,28 +860,28 @@ main_verify_biguint_sub_uint64_route@32: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_mul_route@33: - // tests/artifacts/PrimitiveOps/contract.py:175 +__puya_arc4_router___verify_biguint_mul_route@33: + // tests/artifacts/primitive-ops/contract.algo.ts:203 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:175 + // tests/artifacts/primitive-ops/contract.algo.ts:203 // @arc4.abimethod() callsub verify_biguint_mul dup @@ -939,28 +890,28 @@ main_verify_biguint_mul_route@33: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_mul_uint64_route@34: - // tests/artifacts/PrimitiveOps/contract.py:182 +__puya_arc4_router___verify_biguint_mul_uint64_route@34: + // tests/artifacts/primitive-ops/contract.algo.ts:211 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:182 + // tests/artifacts/primitive-ops/contract.algo.ts:211 // @arc4.abimethod() callsub verify_biguint_mul_uint64 dup @@ -969,28 +920,28 @@ main_verify_biguint_mul_uint64_route@34: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_div_route@35: - // tests/artifacts/PrimitiveOps/contract.py:188 +__puya_arc4_router___verify_biguint_div_route@35: + // tests/artifacts/primitive-ops/contract.algo.ts:219 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:188 + // tests/artifacts/primitive-ops/contract.algo.ts:219 // @arc4.abimethod() callsub verify_biguint_div dup @@ -999,28 +950,28 @@ main_verify_biguint_div_route@35: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_div_uint64_route@36: - // tests/artifacts/PrimitiveOps/contract.py:195 +__puya_arc4_router___verify_biguint_div_uint64_route@36: + // tests/artifacts/primitive-ops/contract.algo.ts:227 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:195 + // tests/artifacts/primitive-ops/contract.algo.ts:227 // @arc4.abimethod() callsub verify_biguint_div_uint64 dup @@ -1029,28 +980,28 @@ main_verify_biguint_div_uint64_route@36: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_mod_route@37: - // tests/artifacts/PrimitiveOps/contract.py:201 +__puya_arc4_router___verify_biguint_mod_route@37: + // tests/artifacts/primitive-ops/contract.algo.ts:235 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:201 + // tests/artifacts/primitive-ops/contract.algo.ts:235 // @arc4.abimethod() callsub verify_biguint_mod dup @@ -1059,28 +1010,28 @@ main_verify_biguint_mod_route@37: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_mod_uint64_route@38: - // tests/artifacts/PrimitiveOps/contract.py:208 +__puya_arc4_router___verify_biguint_mod_uint64_route@38: + // tests/artifacts/primitive-ops/contract.algo.ts:243 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:208 + // tests/artifacts/primitive-ops/contract.algo.ts:243 // @arc4.abimethod() callsub verify_biguint_mod_uint64 dup @@ -1089,28 +1040,28 @@ main_verify_biguint_mod_uint64_route@38: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_and_route@39: - // tests/artifacts/PrimitiveOps/contract.py:214 +__puya_arc4_router___verify_biguint_and_route@39: + // tests/artifacts/primitive-ops/contract.algo.ts:251 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:214 + // tests/artifacts/primitive-ops/contract.algo.ts:251 // @arc4.abimethod() callsub verify_biguint_and dup @@ -1119,28 +1070,28 @@ main_verify_biguint_and_route@39: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_and_uint64_route@40: - // tests/artifacts/PrimitiveOps/contract.py:221 +__puya_arc4_router___verify_biguint_and_uint64_route@40: + // tests/artifacts/primitive-ops/contract.algo.ts:259 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:221 + // tests/artifacts/primitive-ops/contract.algo.ts:259 // @arc4.abimethod() callsub verify_biguint_and_uint64 dup @@ -1149,28 +1100,28 @@ main_verify_biguint_and_uint64_route@40: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_or_route@41: - // tests/artifacts/PrimitiveOps/contract.py:227 +__puya_arc4_router___verify_biguint_or_route@41: + // tests/artifacts/primitive-ops/contract.algo.ts:267 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:227 + // tests/artifacts/primitive-ops/contract.algo.ts:267 // @arc4.abimethod() callsub verify_biguint_or dup @@ -1179,28 +1130,28 @@ main_verify_biguint_or_route@41: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_or_uint64_route@42: - // tests/artifacts/PrimitiveOps/contract.py:234 +__puya_arc4_router___verify_biguint_or_uint64_route@42: + // tests/artifacts/primitive-ops/contract.algo.ts:275 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:234 + // tests/artifacts/primitive-ops/contract.algo.ts:275 // @arc4.abimethod() callsub verify_biguint_or_uint64 dup @@ -1209,28 +1160,28 @@ main_verify_biguint_or_uint64_route@42: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_xor_route@43: - // tests/artifacts/PrimitiveOps/contract.py:240 +__puya_arc4_router___verify_biguint_xor_route@43: + // tests/artifacts/primitive-ops/contract.algo.ts:283 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:240 + // tests/artifacts/primitive-ops/contract.algo.ts:283 // @arc4.abimethod() callsub verify_biguint_xor dup @@ -1239,28 +1190,28 @@ main_verify_biguint_xor_route@43: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_xor_uint64_route@44: - // tests/artifacts/PrimitiveOps/contract.py:247 +__puya_arc4_router___verify_biguint_xor_uint64_route@44: + // tests/artifacts/primitive-ops/contract.algo.ts:291 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:247 + // tests/artifacts/primitive-ops/contract.algo.ts:291 // @arc4.abimethod() callsub verify_biguint_xor_uint64 dup @@ -1269,1617 +1220,1300 @@ main_verify_biguint_xor_uint64_route@44: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_eq_route@45: - // tests/artifacts/PrimitiveOps/contract.py:253 +__puya_arc4_router___verify_biguint_eq_route@45: + // tests/artifacts/primitive-ops/contract.algo.ts:299 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:253 + // tests/artifacts/primitive-ops/contract.algo.ts:299 // @arc4.abimethod() callsub verify_biguint_eq - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_eq_uint64_route@46: - // tests/artifacts/PrimitiveOps/contract.py:260 +__puya_arc4_router___verify_biguint_eq_uint64_route@46: + // tests/artifacts/primitive-ops/contract.algo.ts:307 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:260 + // tests/artifacts/primitive-ops/contract.algo.ts:307 // @arc4.abimethod() callsub verify_biguint_eq_uint64 - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_ne_route@47: - // tests/artifacts/PrimitiveOps/contract.py:266 +__puya_arc4_router___verify_biguint_ne_route@47: + // tests/artifacts/primitive-ops/contract.algo.ts:314 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:266 + // tests/artifacts/primitive-ops/contract.algo.ts:314 // @arc4.abimethod() callsub verify_biguint_ne - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_ne_uint64_route@48: - // tests/artifacts/PrimitiveOps/contract.py:273 +__puya_arc4_router___verify_biguint_ne_uint64_route@48: + // tests/artifacts/primitive-ops/contract.algo.ts:322 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:273 + // tests/artifacts/primitive-ops/contract.algo.ts:322 // @arc4.abimethod() callsub verify_biguint_ne_uint64 - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_lt_route@49: - // tests/artifacts/PrimitiveOps/contract.py:279 +__puya_arc4_router___verify_biguint_lt_route@49: + // tests/artifacts/primitive-ops/contract.algo.ts:329 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:279 + // tests/artifacts/primitive-ops/contract.algo.ts:329 // @arc4.abimethod() callsub verify_biguint_lt - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_lt_uint64_route@50: - // tests/artifacts/PrimitiveOps/contract.py:286 +__puya_arc4_router___verify_biguint_lt_uint64_route@50: + // tests/artifacts/primitive-ops/contract.algo.ts:337 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:286 + // tests/artifacts/primitive-ops/contract.algo.ts:337 // @arc4.abimethod() callsub verify_biguint_lt_uint64 - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_le_route@51: - // tests/artifacts/PrimitiveOps/contract.py:292 +__puya_arc4_router___verify_biguint_le_route@51: + // tests/artifacts/primitive-ops/contract.algo.ts:345 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:292 + // tests/artifacts/primitive-ops/contract.algo.ts:345 // @arc4.abimethod() callsub verify_biguint_le - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_le_uint64_route@52: - // tests/artifacts/PrimitiveOps/contract.py:299 +__puya_arc4_router___verify_biguint_le_uint64_route@52: + // tests/artifacts/primitive-ops/contract.algo.ts:353 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:299 + // tests/artifacts/primitive-ops/contract.algo.ts:353 // @arc4.abimethod() callsub verify_biguint_le_uint64 - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_gt_route@53: - // tests/artifacts/PrimitiveOps/contract.py:305 +__puya_arc4_router___verify_biguint_gt_route@53: + // tests/artifacts/primitive-ops/contract.algo.ts:361 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:305 + // tests/artifacts/primitive-ops/contract.algo.ts:361 // @arc4.abimethod() callsub verify_biguint_gt - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_gt_uint64_route@54: - // tests/artifacts/PrimitiveOps/contract.py:312 +__puya_arc4_router___verify_biguint_gt_uint64_route@54: + // tests/artifacts/primitive-ops/contract.algo.ts:369 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:312 + // tests/artifacts/primitive-ops/contract.algo.ts:369 // @arc4.abimethod() callsub verify_biguint_gt_uint64 - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_ge_route@55: - // tests/artifacts/PrimitiveOps/contract.py:318 +__puya_arc4_router___verify_biguint_ge_route@55: + // tests/artifacts/primitive-ops/contract.algo.ts:377 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:318 + // tests/artifacts/primitive-ops/contract.algo.ts:377 // @arc4.abimethod() callsub verify_biguint_ge - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_biguint_ge_uint64_route@56: - // tests/artifacts/PrimitiveOps/contract.py:325 +__puya_arc4_router___verify_biguint_ge_uint64_route@56: + // tests/artifacts/primitive-ops/contract.algo.ts:385 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is NoOp txn ApplicationID assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txna ApplicationArgs 1 extract 2 0 txna ApplicationArgs 2 btoi - // tests/artifacts/PrimitiveOps/contract.py:325 + // tests/artifacts/primitive-ops/contract.algo.ts:385 // @arc4.abimethod() callsub verify_biguint_ge_uint64 - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return - -main_verify_string_init_route@57: - // tests/artifacts/PrimitiveOps/contract.py:331 - // @arc4.abimethod - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): - txna ApplicationArgs 1 - extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:331 - // @arc4.abimethod - callsub verify_string_init - dup - len - itob - extract 6 2 - swap - concat - byte 0x151f7c75 - swap - concat - log - int 1 - return - -main_verify_string_startswith_route@58: - // tests/artifacts/PrimitiveOps/contract.py:336 - // @arc4.abimethod - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:336 - // @arc4.abimethod - callsub verify_string_startswith - byte 0x00 - int 0 - uncover 2 - setbit - byte 0x151f7c75 - swap - concat - log - int 1 - return - -main_verify_string_endswith_route@59: - // tests/artifacts/PrimitiveOps/contract.py:341 - // @arc4.abimethod - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:341 - // @arc4.abimethod - callsub verify_string_endswith - byte 0x00 - int 0 - uncover 2 - setbit - byte 0x151f7c75 - swap - concat - log - int 1 - return - -main_verify_string_join_route@60: - // tests/artifacts/PrimitiveOps/contract.py:346 - // @arc4.abimethod - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): - txna ApplicationArgs 1 - extract 2 0 - txna ApplicationArgs 2 - extract 2 0 - // tests/artifacts/PrimitiveOps/contract.py:346 - // @arc4.abimethod - callsub verify_string_join - dup - len - itob - extract 6 2 - swap - concat - byte 0x151f7c75 - swap - concat - log - int 1 - return - -main_verify_log_route@61: - // tests/artifacts/PrimitiveOps/contract.py:351 - // @arc4.abimethod - txn OnCompletion - ! - assert // OnCompletion is NoOp - txn ApplicationID - assert // is not creating - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): - 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/PrimitiveOps/contract.py:351 - // @arc4.abimethod - callsub verify_log - int 1 - return + intc_0 // 1 + retsub -main_bare_routing@64: - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): +__puya_arc4_router___bare_routing@59: + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { txn OnCompletion - ! - assert // reject transaction + bnz __puya_arc4_router___after_if_else@63 txn ApplicationID ! assert // is creating - int 1 - return + intc_0 // 1 + retsub + +__puya_arc4_router___after_if_else@63: + // tests/artifacts/primitive-ops/contract.algo.ts:3 + // export class PrimitiveOpsContract extends arc4.Contract { + intc_1 // 0 + retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_init(raw_value: bytes) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_init(raw_value: bytes) -> uint64: verify_uint64_init: - // tests/artifacts/PrimitiveOps/contract.py:7-8 + // tests/artifacts/primitive-ops/contract.algo.ts:4-5 // @arc4.abimethod() - // def verify_uint64_init(self, raw_value: Bytes) -> UInt64: + // public verify_uint64_init(raw_value: bytes): uint64 { proto 1 1 - // tests/artifacts/PrimitiveOps/contract.py:9 - // result = op.btoi(raw_value) + // tests/artifacts/primitive-ops/contract.algo.ts:6 + // const result = op.btoi(raw_value) frame_dig -1 btoi - // tests/artifacts/PrimitiveOps/contract.py:10 + // tests/artifacts/primitive-ops/contract.algo.ts:7 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_add(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_add(a: uint64, b: uint64) -> uint64: verify_uint64_add: - // tests/artifacts/PrimitiveOps/contract.py:12-13 + // tests/artifacts/primitive-ops/contract.algo.ts:10-11 // @arc4.abimethod() - // def verify_uint64_add(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_add(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:14 - // result = a + b + // tests/artifacts/primitive-ops/contract.algo.ts:12 + // const result: uint64 = a + b frame_dig -2 frame_dig -1 + - // tests/artifacts/PrimitiveOps/contract.py:15 + // tests/artifacts/primitive-ops/contract.algo.ts:13 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_sub(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_sub(a: uint64, b: uint64) -> uint64: verify_uint64_sub: - // tests/artifacts/PrimitiveOps/contract.py:17-18 + // tests/artifacts/primitive-ops/contract.algo.ts:16-17 // @arc4.abimethod() - // def verify_uint64_sub(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_sub(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:19 - // result = a - b + // tests/artifacts/primitive-ops/contract.algo.ts:18 + // const result: uint64 = a - b frame_dig -2 frame_dig -1 - - // tests/artifacts/PrimitiveOps/contract.py:20 + // tests/artifacts/primitive-ops/contract.algo.ts:19 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_mul(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_mul(a: uint64, b: uint64) -> uint64: verify_uint64_mul: - // tests/artifacts/PrimitiveOps/contract.py:22-23 + // tests/artifacts/primitive-ops/contract.algo.ts:22-23 // @arc4.abimethod() - // def verify_uint64_mul(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_mul(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:24 - // result = a * b + // tests/artifacts/primitive-ops/contract.algo.ts:24 + // const result: uint64 = a * b frame_dig -2 frame_dig -1 * - // tests/artifacts/PrimitiveOps/contract.py:25 + // tests/artifacts/primitive-ops/contract.algo.ts:25 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_div(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_div(a: uint64, b: uint64) -> uint64: verify_uint64_div: - // tests/artifacts/PrimitiveOps/contract.py:27-28 + // tests/artifacts/primitive-ops/contract.algo.ts:28-29 // @arc4.abimethod() - // def verify_uint64_div(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_div(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:29 - // result = a // b + // tests/artifacts/primitive-ops/contract.algo.ts:30 + // const result: uint64 = a / b frame_dig -2 frame_dig -1 / - // tests/artifacts/PrimitiveOps/contract.py:30 + // tests/artifacts/primitive-ops/contract.algo.ts:31 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_mod(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_mod(a: uint64, b: uint64) -> uint64: verify_uint64_mod: - // tests/artifacts/PrimitiveOps/contract.py:32-33 + // tests/artifacts/primitive-ops/contract.algo.ts:34-35 // @arc4.abimethod() - // def verify_uint64_mod(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_mod(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:34 - // result = a % b + // tests/artifacts/primitive-ops/contract.algo.ts:36 + // const result: uint64 = a % b frame_dig -2 frame_dig -1 % - // tests/artifacts/PrimitiveOps/contract.py:35 + // tests/artifacts/primitive-ops/contract.algo.ts:37 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_and(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_and(a: uint64, b: uint64) -> uint64: verify_uint64_and: - // tests/artifacts/PrimitiveOps/contract.py:37-38 + // tests/artifacts/primitive-ops/contract.algo.ts:40-41 // @arc4.abimethod() - // def verify_uint64_and(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_and(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:39 - // result = a & b + // tests/artifacts/primitive-ops/contract.algo.ts:42 + // const result: uint64 = a & b frame_dig -2 frame_dig -1 & - // tests/artifacts/PrimitiveOps/contract.py:40 + // tests/artifacts/primitive-ops/contract.algo.ts:43 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_or(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_or(a: uint64, b: uint64) -> uint64: verify_uint64_or: - // tests/artifacts/PrimitiveOps/contract.py:42-43 + // tests/artifacts/primitive-ops/contract.algo.ts:46-47 // @arc4.abimethod() - // def verify_uint64_or(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_or(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:44 - // result = a | b + // tests/artifacts/primitive-ops/contract.algo.ts:48 + // const result: uint64 = a | b frame_dig -2 frame_dig -1 | - // tests/artifacts/PrimitiveOps/contract.py:45 + // tests/artifacts/primitive-ops/contract.algo.ts:49 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_xor(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_xor(a: uint64, b: uint64) -> uint64: verify_uint64_xor: - // tests/artifacts/PrimitiveOps/contract.py:47-48 + // tests/artifacts/primitive-ops/contract.algo.ts:52-53 // @arc4.abimethod() - // def verify_uint64_xor(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_xor(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:49 - // result = a ^ b + // tests/artifacts/primitive-ops/contract.algo.ts:54 + // const result: uint64 = a ^ b frame_dig -2 frame_dig -1 ^ - // tests/artifacts/PrimitiveOps/contract.py:50 + // tests/artifacts/primitive-ops/contract.algo.ts:55 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_not(a: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_not(a: uint64) -> uint64: verify_uint64_not: - // tests/artifacts/PrimitiveOps/contract.py:52-53 + // tests/artifacts/primitive-ops/contract.algo.ts:58-59 // @arc4.abimethod() - // def verify_uint64_not(self, a: UInt64) -> UInt64: + // public verify_uint64_not(a: uint64): uint64 { proto 1 1 - // tests/artifacts/PrimitiveOps/contract.py:54 - // result = ~a + // tests/artifacts/primitive-ops/contract.algo.ts:60 + // const result: uint64 = ~a frame_dig -1 ~ - // tests/artifacts/PrimitiveOps/contract.py:55 + // tests/artifacts/primitive-ops/contract.algo.ts:61 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_lshift(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_lshift(a: uint64, b: uint64) -> uint64: verify_uint64_lshift: - // tests/artifacts/PrimitiveOps/contract.py:57-58 + // tests/artifacts/primitive-ops/contract.algo.ts:64-65 // @arc4.abimethod() - // def verify_uint64_lshift(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_lshift(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:59 - // result = a << b + // tests/artifacts/primitive-ops/contract.algo.ts:66 + // const result: uint64 = a << b frame_dig -2 frame_dig -1 shl - // tests/artifacts/PrimitiveOps/contract.py:60 + // tests/artifacts/primitive-ops/contract.algo.ts:67 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_rshift(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_rshift(a: uint64, b: uint64) -> uint64: verify_uint64_rshift: - // tests/artifacts/PrimitiveOps/contract.py:62-63 + // tests/artifacts/primitive-ops/contract.algo.ts:70-71 // @arc4.abimethod() - // def verify_uint64_rshift(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_rshift(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:64 - // result = a >> b + // tests/artifacts/primitive-ops/contract.algo.ts:72 + // const result: uint64 = a >> b frame_dig -2 frame_dig -1 shr - // tests/artifacts/PrimitiveOps/contract.py:65 + // tests/artifacts/primitive-ops/contract.algo.ts:73 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_pow(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_pow(a: uint64, b: uint64) -> uint64: verify_uint64_pow: - // tests/artifacts/PrimitiveOps/contract.py:67-68 + // tests/artifacts/primitive-ops/contract.algo.ts:76-77 // @arc4.abimethod() - // def verify_uint64_pow(self, a: UInt64, b: UInt64) -> UInt64: + // public verify_uint64_pow(a: uint64, b: uint64): uint64 { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:69 - // result = a**b + // tests/artifacts/primitive-ops/contract.algo.ts:78 + // const result: uint64 = a ** b frame_dig -2 frame_dig -1 exp - // tests/artifacts/PrimitiveOps/contract.py:70 + // tests/artifacts/primitive-ops/contract.algo.ts:79 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_eq(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_eq(a: uint64, b: uint64) -> uint64: verify_uint64_eq: - // tests/artifacts/PrimitiveOps/contract.py:72-73 + // tests/artifacts/primitive-ops/contract.algo.ts:82-83 // @arc4.abimethod() - // def verify_uint64_eq(self, a: UInt64, b: UInt64) -> bool: + // public verify_uint64_eq(a: uint64, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:74 - // result = a == b + // tests/artifacts/primitive-ops/contract.algo.ts:84 + // const result = a === b frame_dig -2 frame_dig -1 == - // tests/artifacts/PrimitiveOps/contract.py:75 + // tests/artifacts/primitive-ops/contract.algo.ts:85 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_ne(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_ne(a: uint64, b: uint64) -> uint64: verify_uint64_ne: - // tests/artifacts/PrimitiveOps/contract.py:77-78 + // tests/artifacts/primitive-ops/contract.algo.ts:88-89 // @arc4.abimethod() - // def verify_uint64_ne(self, a: UInt64, b: UInt64) -> bool: + // public verify_uint64_ne(a: uint64, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:79 - // result = a != b + // tests/artifacts/primitive-ops/contract.algo.ts:90 + // const result = a !== b frame_dig -2 frame_dig -1 != - // tests/artifacts/PrimitiveOps/contract.py:80 + // tests/artifacts/primitive-ops/contract.algo.ts:91 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_lt(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_lt(a: uint64, b: uint64) -> uint64: verify_uint64_lt: - // tests/artifacts/PrimitiveOps/contract.py:82-83 + // tests/artifacts/primitive-ops/contract.algo.ts:94-95 // @arc4.abimethod() - // def verify_uint64_lt(self, a: UInt64, b: UInt64) -> bool: + // public verify_uint64_lt(a: uint64, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:84 - // result = a < b + // tests/artifacts/primitive-ops/contract.algo.ts:96 + // const result = a < b frame_dig -2 frame_dig -1 < - // tests/artifacts/PrimitiveOps/contract.py:85 + // tests/artifacts/primitive-ops/contract.algo.ts:97 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_le(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_le(a: uint64, b: uint64) -> uint64: verify_uint64_le: - // tests/artifacts/PrimitiveOps/contract.py:87-88 + // tests/artifacts/primitive-ops/contract.algo.ts:100-101 // @arc4.abimethod() - // def verify_uint64_le(self, a: UInt64, b: UInt64) -> bool: + // public verify_uint64_le(a: uint64, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:89 - // result = a <= b + // tests/artifacts/primitive-ops/contract.algo.ts:102 + // const result = a <= b frame_dig -2 frame_dig -1 <= - // tests/artifacts/PrimitiveOps/contract.py:90 + // tests/artifacts/primitive-ops/contract.algo.ts:103 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_gt(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_gt(a: uint64, b: uint64) -> uint64: verify_uint64_gt: - // tests/artifacts/PrimitiveOps/contract.py:92-93 + // tests/artifacts/primitive-ops/contract.algo.ts:106-107 // @arc4.abimethod() - // def verify_uint64_gt(self, a: UInt64, b: UInt64) -> bool: + // public verify_uint64_gt(a: uint64, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:94 - // result = a > b + // tests/artifacts/primitive-ops/contract.algo.ts:108 + // const result = a > b frame_dig -2 frame_dig -1 > - // tests/artifacts/PrimitiveOps/contract.py:95 + // tests/artifacts/primitive-ops/contract.algo.ts:109 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_uint64_ge(a: uint64, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_uint64_ge(a: uint64, b: uint64) -> uint64: verify_uint64_ge: - // tests/artifacts/PrimitiveOps/contract.py:97-98 + // tests/artifacts/primitive-ops/contract.algo.ts:112-113 // @arc4.abimethod() - // def verify_uint64_ge(self, a: UInt64, b: UInt64) -> bool: + // public verify_uint64_ge(a: uint64, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:99 - // result = a >= b + // tests/artifacts/primitive-ops/contract.algo.ts:114 + // const result = a >= b frame_dig -2 frame_dig -1 >= - // tests/artifacts/PrimitiveOps/contract.py:100 + // tests/artifacts/primitive-ops/contract.algo.ts:115 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_init(raw_value: uint64) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_init(raw_value: uint64) -> bytes: verify_bytes_init: - // tests/artifacts/PrimitiveOps/contract.py:102-103 + // tests/artifacts/primitive-ops/contract.algo.ts:118-119 // @arc4.abimethod() - // def verify_bytes_init(self, raw_value: UInt64) -> Bytes: + // public verify_bytes_init(raw_value: uint64): bytes { proto 1 1 - // tests/artifacts/PrimitiveOps/contract.py:104 - // result = op.itob(raw_value) + // tests/artifacts/primitive-ops/contract.algo.ts:120 + // const result = op.itob(raw_value) frame_dig -1 itob - // tests/artifacts/PrimitiveOps/contract.py:105 + // tests/artifacts/primitive-ops/contract.algo.ts:121 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_add(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64) -> bytes: +// 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/PrimitiveOps/contract.py:107-110 + // tests/artifacts/primitive-ops/contract.algo.ts:124-125 // @arc4.abimethod() - // def verify_bytes_add( - // self, a: Bytes, b: Bytes, pad_a_size: UInt64, pad_b_size: UInt64 - // ) -> Bytes: + // public verify_bytes_add(a: bytes, b: bytes, pad_a_size: uint64, pad_b_size: uint64): bytes { proto 4 1 - // tests/artifacts/PrimitiveOps/contract.py:111 - // a = op.bzero(pad_a_size) + a + // tests/artifacts/primitive-ops/contract.algo.ts:126 + // const paddedA = op.bzero(pad_a_size).concat(a) frame_dig -2 bzero frame_dig -4 concat - frame_bury -4 - // tests/artifacts/PrimitiveOps/contract.py:112 - // b = op.bzero(pad_b_size) + b + // tests/artifacts/primitive-ops/contract.algo.ts:127 + // const paddedB = op.bzero(pad_b_size).concat(b) frame_dig -1 bzero frame_dig -3 concat - frame_bury -3 - // tests/artifacts/PrimitiveOps/contract.py:113 - // result = a + b - frame_dig -4 - frame_dig -3 + // tests/artifacts/primitive-ops/contract.algo.ts:128 + // const result = paddedA.concat(paddedB) concat - // tests/artifacts/PrimitiveOps/contract.py:114 - // result = op.sha256(result) + // tests/artifacts/primitive-ops/contract.algo.ts:129 + // const resultHash = op.sha256(result) sha256 - // tests/artifacts/PrimitiveOps/contract.py:115 - // return result + // tests/artifacts/primitive-ops/contract.algo.ts:130 + // return resultHash retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_eq(a: bytes, b: bytes) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_eq(a: bytes, b: bytes) -> uint64: verify_bytes_eq: - // tests/artifacts/PrimitiveOps/contract.py:117-118 + // tests/artifacts/primitive-ops/contract.algo.ts:133-134 // @arc4.abimethod() - // def verify_bytes_eq(self, a: Bytes, b: Bytes) -> bool: + // public verify_bytes_eq(a: bytes, b: bytes): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:119 - // result = a == b + // tests/artifacts/primitive-ops/contract.algo.ts:135 + // const result = a === b frame_dig -2 frame_dig -1 == - // tests/artifacts/PrimitiveOps/contract.py:120 + // tests/artifacts/primitive-ops/contract.algo.ts:136 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_ne(a: bytes, b: bytes) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_ne(a: bytes, b: bytes) -> uint64: verify_bytes_ne: - // tests/artifacts/PrimitiveOps/contract.py:122-123 + // tests/artifacts/primitive-ops/contract.algo.ts:139-140 // @arc4.abimethod() - // def verify_bytes_ne(self, a: Bytes, b: Bytes) -> bool: + // public verify_bytes_ne(a: bytes, b: bytes): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:124 - // result = a != b + // tests/artifacts/primitive-ops/contract.algo.ts:141 + // const result = a !== b frame_dig -2 frame_dig -1 != - // tests/artifacts/PrimitiveOps/contract.py:125 + // tests/artifacts/primitive-ops/contract.algo.ts:142 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_and(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_and(a: bytes, b: bytes) -> bytes: verify_bytes_and: - // tests/artifacts/PrimitiveOps/contract.py:127-128 + // tests/artifacts/primitive-ops/contract.algo.ts:145-146 // @arc4.abimethod() - // def verify_bytes_and(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_bytes_and(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:129 - // result = a & b + // tests/artifacts/primitive-ops/contract.algo.ts:147 + // const result = a.bitwiseAnd(b) frame_dig -2 frame_dig -1 b& - // tests/artifacts/PrimitiveOps/contract.py:130 + // tests/artifacts/primitive-ops/contract.algo.ts:148 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_or(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_or(a: bytes, b: bytes) -> bytes: verify_bytes_or: - // tests/artifacts/PrimitiveOps/contract.py:132-133 + // tests/artifacts/primitive-ops/contract.algo.ts:151-152 // @arc4.abimethod() - // def verify_bytes_or(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_bytes_or(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:134 - // result = a | b + // tests/artifacts/primitive-ops/contract.algo.ts:153 + // const result = a.bitwiseOr(b) frame_dig -2 frame_dig -1 b| - // tests/artifacts/PrimitiveOps/contract.py:135 + // tests/artifacts/primitive-ops/contract.algo.ts:154 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_xor(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_xor(a: bytes, b: bytes) -> bytes: verify_bytes_xor: - // tests/artifacts/PrimitiveOps/contract.py:137-138 + // tests/artifacts/primitive-ops/contract.algo.ts:157-158 // @arc4.abimethod() - // def verify_bytes_xor(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_bytes_xor(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:139 - // result = a ^ b + // tests/artifacts/primitive-ops/contract.algo.ts:159 + // const result = a.bitwiseXor(b) frame_dig -2 frame_dig -1 b^ - // tests/artifacts/PrimitiveOps/contract.py:140 + // tests/artifacts/primitive-ops/contract.algo.ts:160 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_bytes_not(a: bytes, pad_size: uint64) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_bytes_not(a: bytes, pad_size: uint64) -> bytes: verify_bytes_not: - // tests/artifacts/PrimitiveOps/contract.py:142-143 + // tests/artifacts/primitive-ops/contract.algo.ts:163-164 // @arc4.abimethod() - // def verify_bytes_not(self, a: Bytes, pad_size: UInt64) -> Bytes: + // public verify_bytes_not(a: bytes, pad_size: uint64): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:144 - // a = op.bzero(pad_size) + a + // tests/artifacts/primitive-ops/contract.algo.ts:165 + // const paddedA = op.bzero(pad_size).concat(a) frame_dig -1 bzero frame_dig -2 concat - dup - frame_bury -2 - // tests/artifacts/PrimitiveOps/contract.py:145 - // result = ~a + // tests/artifacts/primitive-ops/contract.algo.ts:166 + // const result = paddedA.bitwiseInvert() b~ - // tests/artifacts/PrimitiveOps/contract.py:146 - // result = op.sha256(result) + // tests/artifacts/primitive-ops/contract.algo.ts:167 + // const resultHash = op.sha256(result) sha256 - // tests/artifacts/PrimitiveOps/contract.py:147 - // return result + // tests/artifacts/primitive-ops/contract.algo.ts:168 + // return resultHash retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_add(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_add(a: bytes, b: bytes) -> bytes: verify_biguint_add: - // tests/artifacts/PrimitiveOps/contract.py:149-150 + // tests/artifacts/primitive-ops/contract.algo.ts:171-172 // @arc4.abimethod() - // def verify_biguint_add(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_biguint_add(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:153 - // result = a_biguint + b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:175 + // const result: biguint = a_biguint + b_biguint frame_dig -2 frame_dig -1 b+ - // tests/artifacts/PrimitiveOps/contract.py:154 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:176 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_add_uint64(a: bytes, b: uint64) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_add_uint64(a: bytes, b: uint64) -> bytes: verify_biguint_add_uint64: - // tests/artifacts/PrimitiveOps/contract.py:156-157 + // tests/artifacts/primitive-ops/contract.algo.ts:179-180 // @arc4.abimethod() - // def verify_biguint_add_uint64(self, a: Bytes, b: UInt64) -> Bytes: + // public verify_biguint_add_uint64(a: bytes, b: uint64): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:159 - // result = a_biguint + b + // tests/artifacts/primitive-ops/contract.algo.ts:182 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:183 + // const result: biguint = a_biguint + b_biguint frame_dig -2 b+ - // tests/artifacts/PrimitiveOps/contract.py:160 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:184 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_sub(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_sub(a: bytes, b: bytes) -> bytes: verify_biguint_sub: - // tests/artifacts/PrimitiveOps/contract.py:162-163 + // tests/artifacts/primitive-ops/contract.algo.ts:187-188 // @arc4.abimethod() - // def verify_biguint_sub(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_biguint_sub(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:166 - // result = a_biguint - b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:191 + // const result: biguint = a_biguint - b_biguint frame_dig -2 frame_dig -1 b- - // tests/artifacts/PrimitiveOps/contract.py:167 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:192 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_sub_uint64(a: bytes, b: uint64) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_sub_uint64(a: bytes, b: uint64) -> bytes: verify_biguint_sub_uint64: - // tests/artifacts/PrimitiveOps/contract.py:169-170 + // tests/artifacts/primitive-ops/contract.algo.ts:195-196 // @arc4.abimethod() - // def verify_biguint_sub_uint64(self, a: Bytes, b: UInt64) -> Bytes: + // public verify_biguint_sub_uint64(a: bytes, b: uint64): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:172 - // result = a_biguint - b + // tests/artifacts/primitive-ops/contract.algo.ts:198 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:199 + // const result: biguint = a_biguint - b_biguint frame_dig -2 swap b- - // tests/artifacts/PrimitiveOps/contract.py:173 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:200 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_mul(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_mul(a: bytes, b: bytes) -> bytes: verify_biguint_mul: - // tests/artifacts/PrimitiveOps/contract.py:175-176 + // tests/artifacts/primitive-ops/contract.algo.ts:203-204 // @arc4.abimethod() - // def verify_biguint_mul(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_biguint_mul(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:179 - // result = a_biguint * b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:207 + // const result: biguint = a_biguint * b_biguint frame_dig -2 frame_dig -1 b* - // tests/artifacts/PrimitiveOps/contract.py:180 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:208 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_mul_uint64(a: bytes, b: uint64) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_mul_uint64(a: bytes, b: uint64) -> bytes: verify_biguint_mul_uint64: - // tests/artifacts/PrimitiveOps/contract.py:182-183 + // tests/artifacts/primitive-ops/contract.algo.ts:211-212 // @arc4.abimethod() - // def verify_biguint_mul_uint64(self, a: Bytes, b: UInt64) -> Bytes: + // public verify_biguint_mul_uint64(a: bytes, b: uint64): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:185 - // result = a_biguint * b + // tests/artifacts/primitive-ops/contract.algo.ts:214 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:215 + // const result: biguint = a_biguint * b_biguint frame_dig -2 b* - // tests/artifacts/PrimitiveOps/contract.py:186 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:216 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_div(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_div(a: bytes, b: bytes) -> bytes: verify_biguint_div: - // tests/artifacts/PrimitiveOps/contract.py:188-189 + // tests/artifacts/primitive-ops/contract.algo.ts:219-220 // @arc4.abimethod() - // def verify_biguint_div(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_biguint_div(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:192 - // result = a_biguint // b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:223 + // const result: biguint = a_biguint / b_biguint frame_dig -2 frame_dig -1 b/ - // tests/artifacts/PrimitiveOps/contract.py:193 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:224 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_div_uint64(a: bytes, b: uint64) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_div_uint64(a: bytes, b: uint64) -> bytes: verify_biguint_div_uint64: - // tests/artifacts/PrimitiveOps/contract.py:195-196 + // tests/artifacts/primitive-ops/contract.algo.ts:227-228 // @arc4.abimethod() - // def verify_biguint_div_uint64(self, a: Bytes, b: UInt64) -> Bytes: + // public verify_biguint_div_uint64(a: bytes, b: uint64): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:198 - // result = a_biguint // b + // tests/artifacts/primitive-ops/contract.algo.ts:230 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:231 + // const result: biguint = a_biguint / b_biguint frame_dig -2 swap b/ - // tests/artifacts/PrimitiveOps/contract.py:199 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:232 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_mod(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_mod(a: bytes, b: bytes) -> bytes: verify_biguint_mod: - // tests/artifacts/PrimitiveOps/contract.py:201-202 + // tests/artifacts/primitive-ops/contract.algo.ts:235-236 // @arc4.abimethod() - // def verify_biguint_mod(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_biguint_mod(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:205 - // result = a_biguint % b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:239 + // const result: biguint = a_biguint % b_biguint frame_dig -2 frame_dig -1 b% - // tests/artifacts/PrimitiveOps/contract.py:206 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:240 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_mod_uint64(a: bytes, b: uint64) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_mod_uint64(a: bytes, b: uint64) -> bytes: verify_biguint_mod_uint64: - // tests/artifacts/PrimitiveOps/contract.py:208-209 + // tests/artifacts/primitive-ops/contract.algo.ts:243-244 // @arc4.abimethod() - // def verify_biguint_mod_uint64(self, a: Bytes, b: UInt64) -> Bytes: + // public verify_biguint_mod_uint64(a: bytes, b: uint64): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:211 - // result = a_biguint % b + // tests/artifacts/primitive-ops/contract.algo.ts:246 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:247 + // const result: biguint = a_biguint % b_biguint frame_dig -2 swap b% - // tests/artifacts/PrimitiveOps/contract.py:212 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:248 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_and(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_and(a: bytes, b: bytes) -> bytes: verify_biguint_and: - // tests/artifacts/PrimitiveOps/contract.py:214-215 + // tests/artifacts/primitive-ops/contract.algo.ts:251-252 // @arc4.abimethod() - // def verify_biguint_and(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_biguint_and(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:218 - // result = a_biguint & b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:255 + // const result: biguint = a_biguint & b_biguint frame_dig -2 frame_dig -1 b& - // tests/artifacts/PrimitiveOps/contract.py:219 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:256 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_and_uint64(a: bytes, b: uint64) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_and_uint64(a: bytes, b: uint64) -> bytes: verify_biguint_and_uint64: - // tests/artifacts/PrimitiveOps/contract.py:221-222 + // tests/artifacts/primitive-ops/contract.algo.ts:259-260 // @arc4.abimethod() - // def verify_biguint_and_uint64(self, a: Bytes, b: UInt64) -> Bytes: + // public verify_biguint_and_uint64(a: bytes, b: uint64): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:224 - // result = a_biguint & b + // tests/artifacts/primitive-ops/contract.algo.ts:262 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:263 + // const result: biguint = a_biguint & b_biguint frame_dig -2 b& - // tests/artifacts/PrimitiveOps/contract.py:225 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:264 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_or(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_or(a: bytes, b: bytes) -> bytes: verify_biguint_or: - // tests/artifacts/PrimitiveOps/contract.py:227-228 + // tests/artifacts/primitive-ops/contract.algo.ts:267-268 // @arc4.abimethod() - // def verify_biguint_or(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_biguint_or(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:231 - // result = a_biguint | b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:271 + // const result: biguint = a_biguint | b_biguint frame_dig -2 frame_dig -1 b| - // tests/artifacts/PrimitiveOps/contract.py:232 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:272 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_or_uint64(a: bytes, b: uint64) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_or_uint64(a: bytes, b: uint64) -> bytes: verify_biguint_or_uint64: - // tests/artifacts/PrimitiveOps/contract.py:234-235 + // tests/artifacts/primitive-ops/contract.algo.ts:275-276 // @arc4.abimethod() - // def verify_biguint_or_uint64(self, a: Bytes, b: UInt64) -> Bytes: + // public verify_biguint_or_uint64(a: bytes, b: uint64): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:237 - // result = a_biguint | b + // tests/artifacts/primitive-ops/contract.algo.ts:278 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:279 + // const result: biguint = a_biguint | b_biguint frame_dig -2 b| - // tests/artifacts/PrimitiveOps/contract.py:238 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:280 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_xor(a: bytes, b: bytes) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_xor(a: bytes, b: bytes) -> bytes: verify_biguint_xor: - // tests/artifacts/PrimitiveOps/contract.py:240-241 + // tests/artifacts/primitive-ops/contract.algo.ts:283-284 // @arc4.abimethod() - // def verify_biguint_xor(self, a: Bytes, b: Bytes) -> Bytes: + // public verify_biguint_xor(a: bytes, b: bytes): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:244 - // result = a_biguint ^ b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:287 + // const result: biguint = a_biguint ^ b_biguint frame_dig -2 frame_dig -1 b^ - // tests/artifacts/PrimitiveOps/contract.py:245 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:288 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_xor_uint64(a: bytes, b: uint64) -> bytes: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_xor_uint64(a: bytes, b: uint64) -> bytes: verify_biguint_xor_uint64: - // tests/artifacts/PrimitiveOps/contract.py:247-248 + // tests/artifacts/primitive-ops/contract.algo.ts:291-292 // @arc4.abimethod() - // def verify_biguint_xor_uint64(self, a: Bytes, b: UInt64) -> Bytes: + // public verify_biguint_xor_uint64(a: bytes, b: uint64): bytes { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:250 - // result = a_biguint ^ b + // tests/artifacts/primitive-ops/contract.algo.ts:294 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:295 + // const result: biguint = a_biguint ^ b_biguint frame_dig -2 b^ - // tests/artifacts/PrimitiveOps/contract.py:251 - // return result.bytes + // tests/artifacts/primitive-ops/contract.algo.ts:296 + // return Bytes(result) retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_eq(a: bytes, b: bytes) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_eq(a: bytes, b: bytes) -> uint64: verify_biguint_eq: - // tests/artifacts/PrimitiveOps/contract.py:253-254 + // tests/artifacts/primitive-ops/contract.algo.ts:299-300 // @arc4.abimethod() - // def verify_biguint_eq(self, a: Bytes, b: Bytes) -> bool: + // public verify_biguint_eq(a: bytes, b: bytes): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:257 - // result = a_biguint == b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:303 + // const result = a_biguint === b_biguint frame_dig -2 frame_dig -1 b== - // tests/artifacts/PrimitiveOps/contract.py:258 + // tests/artifacts/primitive-ops/contract.algo.ts:304 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_eq_uint64(a: bytes, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_eq_uint64(a: bytes, b: uint64) -> uint64: verify_biguint_eq_uint64: - // tests/artifacts/PrimitiveOps/contract.py:260-261 + // tests/artifacts/primitive-ops/contract.algo.ts:307-308 // @arc4.abimethod() - // def verify_biguint_eq_uint64(self, a: Bytes, b: UInt64) -> bool: + // public verify_biguint_eq_uint64(a: bytes, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:263 - // result = a_biguint == b + // tests/artifacts/primitive-ops/contract.algo.ts:310 + // const result = a_biguint === BigUint(b) frame_dig -1 itob frame_dig -2 b== - // tests/artifacts/PrimitiveOps/contract.py:264 + // tests/artifacts/primitive-ops/contract.algo.ts:311 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_ne(a: bytes, b: bytes) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_ne(a: bytes, b: bytes) -> uint64: verify_biguint_ne: - // tests/artifacts/PrimitiveOps/contract.py:266-267 + // tests/artifacts/primitive-ops/contract.algo.ts:314-315 // @arc4.abimethod() - // def verify_biguint_ne(self, a: Bytes, b: Bytes) -> bool: + // public verify_biguint_ne(a: bytes, b: bytes): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:270 - // result = a_biguint != b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:318 + // const result = a_biguint !== b_biguint frame_dig -2 frame_dig -1 b!= - // tests/artifacts/PrimitiveOps/contract.py:271 + // tests/artifacts/primitive-ops/contract.algo.ts:319 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_ne_uint64(a: bytes, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_ne_uint64(a: bytes, b: uint64) -> uint64: verify_biguint_ne_uint64: - // tests/artifacts/PrimitiveOps/contract.py:273-274 + // tests/artifacts/primitive-ops/contract.algo.ts:322-323 // @arc4.abimethod() - // def verify_biguint_ne_uint64(self, a: Bytes, b: UInt64) -> bool: + // public verify_biguint_ne_uint64(a: bytes, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:276 - // result = a_biguint != b + // tests/artifacts/primitive-ops/contract.algo.ts:325 + // const result = a_biguint !== BigUint(b) frame_dig -1 itob frame_dig -2 b!= - // tests/artifacts/PrimitiveOps/contract.py:277 + // tests/artifacts/primitive-ops/contract.algo.ts:326 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_lt(a: bytes, b: bytes) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_lt(a: bytes, b: bytes) -> uint64: verify_biguint_lt: - // tests/artifacts/PrimitiveOps/contract.py:279-280 + // tests/artifacts/primitive-ops/contract.algo.ts:329-330 // @arc4.abimethod() - // def verify_biguint_lt(self, a: Bytes, b: Bytes) -> bool: + // public verify_biguint_lt(a: bytes, b: bytes): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:283 - // result = a_biguint < b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:333 + // const result = a_biguint < b_biguint frame_dig -2 frame_dig -1 b< - // tests/artifacts/PrimitiveOps/contract.py:284 + // tests/artifacts/primitive-ops/contract.algo.ts:334 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_lt_uint64(a: bytes, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_lt_uint64(a: bytes, b: uint64) -> uint64: verify_biguint_lt_uint64: - // tests/artifacts/PrimitiveOps/contract.py:286-287 + // tests/artifacts/primitive-ops/contract.algo.ts:337-338 // @arc4.abimethod() - // def verify_biguint_lt_uint64(self, a: Bytes, b: UInt64) -> bool: + // public verify_biguint_lt_uint64(a: bytes, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:289 - // result = a_biguint < b + // tests/artifacts/primitive-ops/contract.algo.ts:340 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:341 + // const result = a_biguint < b_biguint frame_dig -2 b> - // tests/artifacts/PrimitiveOps/contract.py:290 + // tests/artifacts/primitive-ops/contract.algo.ts:342 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_le(a: bytes, b: bytes) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_le(a: bytes, b: bytes) -> uint64: verify_biguint_le: - // tests/artifacts/PrimitiveOps/contract.py:292-293 + // tests/artifacts/primitive-ops/contract.algo.ts:345-346 // @arc4.abimethod() - // def verify_biguint_le(self, a: Bytes, b: Bytes) -> bool: + // public verify_biguint_le(a: bytes, b: bytes): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:296 - // result = a_biguint <= b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:349 + // const result = a_biguint <= b_biguint frame_dig -2 frame_dig -1 b<= - // tests/artifacts/PrimitiveOps/contract.py:297 + // tests/artifacts/primitive-ops/contract.algo.ts:350 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_le_uint64(a: bytes, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_le_uint64(a: bytes, b: uint64) -> uint64: verify_biguint_le_uint64: - // tests/artifacts/PrimitiveOps/contract.py:299-300 + // tests/artifacts/primitive-ops/contract.algo.ts:353-354 // @arc4.abimethod() - // def verify_biguint_le_uint64(self, a: Bytes, b: UInt64) -> bool: + // public verify_biguint_le_uint64(a: bytes, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:302 - // result = a_biguint <= b + // tests/artifacts/primitive-ops/contract.algo.ts:356 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:357 + // const result = a_biguint <= b_biguint frame_dig -2 b>= - // tests/artifacts/PrimitiveOps/contract.py:303 + // tests/artifacts/primitive-ops/contract.algo.ts:358 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_gt(a: bytes, b: bytes) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_gt(a: bytes, b: bytes) -> uint64: verify_biguint_gt: - // tests/artifacts/PrimitiveOps/contract.py:305-306 + // tests/artifacts/primitive-ops/contract.algo.ts:361-362 // @arc4.abimethod() - // def verify_biguint_gt(self, a: Bytes, b: Bytes) -> bool: + // public verify_biguint_gt(a: bytes, b: bytes): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:309 - // result = a_biguint > b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:365 + // const result = a_biguint > b_biguint frame_dig -2 frame_dig -1 b> - // tests/artifacts/PrimitiveOps/contract.py:310 + // tests/artifacts/primitive-ops/contract.algo.ts:366 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_gt_uint64(a: bytes, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_gt_uint64(a: bytes, b: uint64) -> uint64: verify_biguint_gt_uint64: - // tests/artifacts/PrimitiveOps/contract.py:312-313 + // tests/artifacts/primitive-ops/contract.algo.ts:369-370 // @arc4.abimethod() - // def verify_biguint_gt_uint64(self, a: Bytes, b: UInt64) -> bool: + // public verify_biguint_gt_uint64(a: bytes, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:315 - // result = a_biguint > b + // tests/artifacts/primitive-ops/contract.algo.ts:372 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:373 + // const result = a_biguint > b_biguint frame_dig -2 b< - // tests/artifacts/PrimitiveOps/contract.py:316 + // tests/artifacts/primitive-ops/contract.algo.ts:374 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_ge(a: bytes, b: bytes) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_ge(a: bytes, b: bytes) -> uint64: verify_biguint_ge: - // tests/artifacts/PrimitiveOps/contract.py:318-319 + // tests/artifacts/primitive-ops/contract.algo.ts:377-378 // @arc4.abimethod() - // def verify_biguint_ge(self, a: Bytes, b: Bytes) -> bool: + // public verify_biguint_ge(a: bytes, b: bytes): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:322 - // result = a_biguint >= b_biguint + // tests/artifacts/primitive-ops/contract.algo.ts:381 + // const result = a_biguint >= b_biguint frame_dig -2 frame_dig -1 b>= - // tests/artifacts/PrimitiveOps/contract.py:323 + // tests/artifacts/primitive-ops/contract.algo.ts:382 // return result retsub -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_biguint_ge_uint64(a: bytes, b: uint64) -> uint64: +// tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.verify_biguint_ge_uint64(a: bytes, b: uint64) -> uint64: verify_biguint_ge_uint64: - // tests/artifacts/PrimitiveOps/contract.py:325-326 + // tests/artifacts/primitive-ops/contract.algo.ts:385-386 // @arc4.abimethod() - // def verify_biguint_ge_uint64(self, a: Bytes, b: UInt64) -> bool: + // public verify_biguint_ge_uint64(a: bytes, b: uint64): boolean { proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:328 - // result = a_biguint >= b + // tests/artifacts/primitive-ops/contract.algo.ts:388 + // const b_biguint = BigUint(b) frame_dig -1 itob + // tests/artifacts/primitive-ops/contract.algo.ts:389 + // const result = a_biguint >= b_biguint frame_dig -2 b<= - // tests/artifacts/PrimitiveOps/contract.py:329 - // return result - retsub - - -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_string_init(a: bytes) -> bytes: -verify_string_init: - // tests/artifacts/PrimitiveOps/contract.py:331-332 - // @arc4.abimethod - // def verify_string_init(self, a: String) -> String: - proto 1 1 - // tests/artifacts/PrimitiveOps/contract.py:333 - // result = String("Hello, ") + a - byte "Hello, " - frame_dig -1 - concat - // tests/artifacts/PrimitiveOps/contract.py:334 - // return result - retsub - - -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_string_startswith(a: bytes, b: bytes) -> uint64: -verify_string_startswith: - // tests/artifacts/PrimitiveOps/contract.py:336-337 - // @arc4.abimethod - // def verify_string_startswith(self, a: String, b: String) -> bool: - proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:338 - // result = a.startswith(b) - frame_dig -1 - len - dup - frame_dig -2 - len - > - bz verify_string_startswith_ternary_false@2 - int 0 - b verify_string_startswith_ternary_merge@3 - -verify_string_startswith_ternary_false@2: - // tests/artifacts/PrimitiveOps/contract.py:338 - // result = a.startswith(b) - frame_dig -2 - int 0 - frame_dig 0 - extract3 - frame_dig -1 - == - -verify_string_startswith_ternary_merge@3: - // tests/artifacts/PrimitiveOps/contract.py:339 - // return result - swap - retsub - - -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_string_endswith(a: bytes, b: bytes) -> uint64: -verify_string_endswith: - // tests/artifacts/PrimitiveOps/contract.py:341-342 - // @arc4.abimethod - // def verify_string_endswith(self, a: String, b: String) -> bool: - proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:343 - // result = a.endswith(b) - frame_dig -1 - len - dup - frame_dig -2 - len - dup - cover 2 - > - bz verify_string_endswith_ternary_false@2 - int 0 - b verify_string_endswith_ternary_merge@3 - -verify_string_endswith_ternary_false@2: - // tests/artifacts/PrimitiveOps/contract.py:343 - // result = a.endswith(b) - frame_dig 1 - frame_dig 0 - dup - cover 2 - - - frame_dig -2 - swap - uncover 2 - extract3 - frame_dig -1 - == - -verify_string_endswith_ternary_merge@3: - // tests/artifacts/PrimitiveOps/contract.py:344 - // return result - frame_bury 0 - retsub - - -// tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.verify_string_join(a: bytes, b: bytes) -> bytes: -verify_string_join: - // tests/artifacts/PrimitiveOps/contract.py:346-347 - // @arc4.abimethod - // def verify_string_join(self, a: String, b: String) -> String: - proto 2 1 - // tests/artifacts/PrimitiveOps/contract.py:348 - // result = String(", ").join((a, b)) - frame_dig -2 - byte ", " - concat - frame_dig -1 - concat - // tests/artifacts/PrimitiveOps/contract.py:349 + // tests/artifacts/primitive-ops/contract.algo.ts:390 // return result retsub - - -// tests.artifacts.PrimitiveOps.contract.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/PrimitiveOps/contract.py:351-367 - // @arc4.abimethod - // def verify_log( # noqa: PLR0913 - // self, - // a: String, - // b: UInt64, - // c: Bytes, - // d: Bytes, - // e: arc4.Bool, - // f: arc4.String, - // g: arc4.UIntN[typing.Literal[64]], - // h: arc4.BigUIntN[typing.Literal[256]], - // i: arc4.UFixedNxM[typing.Literal[32], typing.Literal[8]], - // j: arc4.BigUFixedNxM[typing.Literal[256], typing.Literal[16]], - // k: Bytes, - // m: Bytes, - // n: Bytes, - // ) -> None: - proto 13 0 - // tests/artifacts/PrimitiveOps/contract.py:372 - // log(a, b, c, d_biguint, e, f, g, h, i, j, arc4_k, arc4_m, arc4_n, sep="-") - frame_dig -13 - byte "-" - concat - frame_dig -12 - itob - concat - byte "-" - concat - frame_dig -11 - concat - byte "-" - concat - frame_dig -10 - concat - byte "-" - concat - frame_dig -9 - concat - byte "-" - concat - frame_dig -8 - concat - byte "-" - concat - frame_dig -7 - concat - byte "-" - concat - frame_dig -6 - concat - byte "-" - concat - frame_dig -5 - concat - byte "-" - concat - frame_dig -4 - concat - byte "-" - concat - frame_dig -3 - concat - byte "-" - concat - frame_dig -2 - concat - byte "-" - 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 index 0a9d7e5..26d987d 100644 --- a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json +++ b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json @@ -274,36 +274,11 @@ "call_config": { "no_op": "CALL" } - }, - "verify_string_init(string)string": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_string_startswith(string,string)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_string_endswith(string,string)bool": { - "call_config": { - "no_op": "CALL" - } - }, - "verify_string_join(string,string)string": { - "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": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdANjQKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9pbml0KGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfYWRkKHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X3N1Yih1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9tdWwodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfZGl2KHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X21vZCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9hbmQodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfb3IodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfeG9yKHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X25vdCh1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2xzaGlmdCh1aW50NjQsdWludDY0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9yc2hpZnQodWludDY0LHVpbnQ2NCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfcG93KHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2VxKHVpbnQ2NCx1aW50NjQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9uZSh1aW50NjQsdWludDY0KWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfbHQodWludDY0LHVpbnQ2NClib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2xlKHVpbnQ2NCx1aW50NjQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9ndCh1aW50NjQsdWludDY0KWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV91aW50NjRfZ2UodWludDY0LHVpbnQ2NClib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfaW5pdCh1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfYWRkKGJ5dGVbXSxieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9ieXRlc19lcShieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9ieXRlc19uZShieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9ieXRlc19hbmQoYnl0ZVtdLGJ5dGVbXSlieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9ieXRlc19vcihieXRlW10sYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2J5dGVzX3hvcihieXRlW10sYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2J5dGVzX25vdChieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfYWRkKGJ5dGVbXSxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9hZGRfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9zdWIoYnl0ZVtdLGJ5dGVbXSlieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X211bChieXRlW10sYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZGl2KGJ5dGVbXSxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9kaXZfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9tb2QoYnl0ZVtdLGJ5dGVbXSlieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X21vZF91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X2FuZChieXRlW10sYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfb3IoYnl0ZVtdLGJ5dGVbXSlieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfeG9yKGJ5dGVbXSxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF94b3JfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9lcShieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X25lKGJ5dGVbXSxieXRlW10pYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbHQoYnl0ZVtdLGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9sdF91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9sZShieXRlW10sYnl0ZVtdKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X2xlX3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9iaWd1aW50X2d0KGJ5dGVbXSxieXRlW10pYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9nZV91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2luaXQoc3RyaW5nKXN0cmluZyIKICAgIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19zdGFydHN3aXRoKHN0cmluZyxzdHJpbmcpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19lbmRzd2l0aChzdHJpbmcsc3RyaW5nKWJvb2wiCiAgICBtZXRob2QgInZlcmlmeV9zdHJpbmdfam9pbihzdHJpbmcsc3RyaW5nKXN0cmluZyIKICAgIG1ldGhvZCAidmVyaWZ5X2xvZyhzdHJpbmcsdWludDY0LGJ5dGVbXSxieXRlW10sYm9vbCxzdHJpbmcsdWludDY0LHVpbnQyNTYsdWZpeGVkMzJ4OCx1Zml4ZWQyNTZ4MTYsYnl0ZVtdLGJ5dGVbXSxieXRlW10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X3VpbnQ2NF9pbml0X3JvdXRlQDIgbWFpbl92ZXJpZnlfdWludDY0X2FkZF9yb3V0ZUAzIG1haW5fdmVyaWZ5X3VpbnQ2NF9zdWJfcm91dGVANCBtYWluX3ZlcmlmeV91aW50NjRfbXVsX3JvdXRlQDUgbWFpbl92ZXJpZnlfdWludDY0X2Rpdl9yb3V0ZUA2IG1haW5fdmVyaWZ5X3VpbnQ2NF9tb2Rfcm91dGVANyBtYWluX3ZlcmlmeV91aW50NjRfYW5kX3JvdXRlQDggbWFpbl92ZXJpZnlfdWludDY0X29yX3JvdXRlQDkgbWFpbl92ZXJpZnlfdWludDY0X3hvcl9yb3V0ZUAxMCBtYWluX3ZlcmlmeV91aW50NjRfbm90X3JvdXRlQDExIG1haW5fdmVyaWZ5X3VpbnQ2NF9sc2hpZnRfcm91dGVAMTIgbWFpbl92ZXJpZnlfdWludDY0X3JzaGlmdF9yb3V0ZUAxMyBtYWluX3ZlcmlmeV91aW50NjRfcG93X3JvdXRlQDE0IG1haW5fdmVyaWZ5X3VpbnQ2NF9lcV9yb3V0ZUAxNSBtYWluX3ZlcmlmeV91aW50NjRfbmVfcm91dGVAMTYgbWFpbl92ZXJpZnlfdWludDY0X2x0X3JvdXRlQDE3IG1haW5fdmVyaWZ5X3VpbnQ2NF9sZV9yb3V0ZUAxOCBtYWluX3ZlcmlmeV91aW50NjRfZ3Rfcm91dGVAMTkgbWFpbl92ZXJpZnlfdWludDY0X2dlX3JvdXRlQDIwIG1haW5fdmVyaWZ5X2J5dGVzX2luaXRfcm91dGVAMjEgbWFpbl92ZXJpZnlfYnl0ZXNfYWRkX3JvdXRlQDIyIG1haW5fdmVyaWZ5X2J5dGVzX2VxX3JvdXRlQDIzIG1haW5fdmVyaWZ5X2J5dGVzX25lX3JvdXRlQDI0IG1haW5fdmVyaWZ5X2J5dGVzX2FuZF9yb3V0ZUAyNSBtYWluX3ZlcmlmeV9ieXRlc19vcl9yb3V0ZUAyNiBtYWluX3ZlcmlmeV9ieXRlc194b3Jfcm91dGVAMjcgbWFpbl92ZXJpZnlfYnl0ZXNfbm90X3JvdXRlQDI4IG1haW5fdmVyaWZ5X2JpZ3VpbnRfYWRkX3JvdXRlQDI5IG1haW5fdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NF9yb3V0ZUAzMCBtYWluX3ZlcmlmeV9iaWd1aW50X3N1Yl9yb3V0ZUAzMSBtYWluX3ZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjRfcm91dGVAMzIgbWFpbl92ZXJpZnlfYmlndWludF9tdWxfcm91dGVAMzMgbWFpbl92ZXJpZnlfYmlndWludF9tdWxfdWludDY0X3JvdXRlQDM0IG1haW5fdmVyaWZ5X2JpZ3VpbnRfZGl2X3JvdXRlQDM1IG1haW5fdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NF9yb3V0ZUAzNiBtYWluX3ZlcmlmeV9iaWd1aW50X21vZF9yb3V0ZUAzNyBtYWluX3ZlcmlmeV9iaWd1aW50X21vZF91aW50NjRfcm91dGVAMzggbWFpbl92ZXJpZnlfYmlndWludF9hbmRfcm91dGVAMzkgbWFpbl92ZXJpZnlfYmlndWludF9hbmRfdWludDY0X3JvdXRlQDQwIG1haW5fdmVyaWZ5X2JpZ3VpbnRfb3Jfcm91dGVANDEgbWFpbl92ZXJpZnlfYmlndWludF9vcl91aW50NjRfcm91dGVANDIgbWFpbl92ZXJpZnlfYmlndWludF94b3Jfcm91dGVANDMgbWFpbl92ZXJpZnlfYmlndWludF94b3JfdWludDY0X3JvdXRlQDQ0IG1haW5fdmVyaWZ5X2JpZ3VpbnRfZXFfcm91dGVANDUgbWFpbl92ZXJpZnlfYmlndWludF9lcV91aW50NjRfcm91dGVANDYgbWFpbl92ZXJpZnlfYmlndWludF9uZV9yb3V0ZUA0NyBtYWluX3ZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NF9yb3V0ZUA0OCBtYWluX3ZlcmlmeV9iaWd1aW50X2x0X3JvdXRlQDQ5IG1haW5fdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0X3JvdXRlQDUwIG1haW5fdmVyaWZ5X2JpZ3VpbnRfbGVfcm91dGVANTEgbWFpbl92ZXJpZnlfYmlndWludF9sZV91aW50NjRfcm91dGVANTIgbWFpbl92ZXJpZnlfYmlndWludF9ndF9yb3V0ZUA1MyBtYWluX3ZlcmlmeV9iaWd1aW50X2d0X3VpbnQ2NF9yb3V0ZUA1NCBtYWluX3ZlcmlmeV9iaWd1aW50X2dlX3JvdXRlQDU1IG1haW5fdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0X3JvdXRlQDU2IG1haW5fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDU3IG1haW5fdmVyaWZ5X3N0cmluZ19zdGFydHN3aXRoX3JvdXRlQDU4IG1haW5fdmVyaWZ5X3N0cmluZ19lbmRzd2l0aF9yb3V0ZUA1OSBtYWluX3ZlcmlmeV9zdHJpbmdfam9pbl9yb3V0ZUA2MCBtYWluX3ZlcmlmeV9sb2dfcm91dGVANjEKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X3VpbnQ2NF9pbml0X3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2luaXQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9hZGRfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2FkZAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludDY0X3N1Yl9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfc3ViCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50NjRfbXVsX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9tdWwKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9kaXZfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2RpdgogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludDY0X21vZF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfbW9kCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50NjRfYW5kX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9hbmQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9vcl9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfb3IKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF94b3Jfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF94b3IKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9ub3Rfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9ub3QKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9sc2hpZnRfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9sc2hpZnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9yc2hpZnRfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9yc2hpZnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9wb3dfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9wb3cKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9lcV9yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2VxCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludDY0X25lX3JvdXRlQDE2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfbmUKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50NjRfbHRfcm91dGVAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9sdAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3VpbnQ2NF9sZV9yb3V0ZUAxODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2xlCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfdWludDY0X2d0X3JvdXRlQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6OTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfZ3QKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV91aW50NjRfZ2Vfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9nZQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX2luaXRfcm91dGVAMjE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTAyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfaW5pdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX2FkZF9yb3V0ZUAyMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEwNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2FkZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX2VxX3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfZXEKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9ieXRlc19uZV9yb3V0ZUAyNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX25lCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZXNfYW5kX3JvdXRlQDI1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfYW5kCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYnl0ZXNfb3Jfcm91dGVAMjY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19vcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX3hvcl9yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX3hvcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2J5dGVzX25vdF9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfbm90CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9hZGRfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FkZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NF9yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9hZGRfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9zdWJfcm91dGVAMzE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X3N1YgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NF9yb3V0ZUAzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9zdWJfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9tdWxfcm91dGVAMzM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X211bAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NF9yb3V0ZUAzNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tdWxfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9kaXZfcm91dGVAMzU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2RpdgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NF9yb3V0ZUAzNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9kaXZfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9tb2Rfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X21vZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NF9yb3V0ZUAzODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjA4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjA4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tb2RfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9hbmRfcm91dGVAMzk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIxNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FuZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NF9yb3V0ZUA0MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9hbmRfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9vcl9yb3V0ZUA0MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfb3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NF9yb3V0ZUA0MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9vcl91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X3hvcl9yb3V0ZUA0MzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfeG9yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF94b3JfdWludDY0X3JvdXRlQDQ0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X2VxX3JvdXRlQDQ1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9lcQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0X3JvdXRlQDQ2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfbmVfcm91dGVANDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X25lCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9uZV91aW50NjRfcm91dGVANDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0CiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9sdF9yb3V0ZUA0OToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjc5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbHQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X2x0X3VpbnQ2NF9yb3V0ZUA1MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sdF91aW50NjQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X2xlX3JvdXRlQDUxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyOTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sZQogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0X3JvdXRlQDUyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2xlX3VpbnQ2NAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2JpZ3VpbnRfZ3Rfcm91dGVANTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2d0CiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9ndF91aW50NjRfcm91dGVANTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0CiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYmlndWludF9nZV9yb3V0ZUA1NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMxOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfZ2UKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9iaWd1aW50X2dlX3VpbnQ2NF9yb3V0ZUA1NjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9nZV91aW50NjQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9zdHJpbmdfaW5pdF9yb3V0ZUA1NzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzMxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfaW5pdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3N0cmluZ19zdGFydHN3aXRoX3JvdXRlQDU4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMzNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3N0cmluZ19lbmRzd2l0aF9yb3V0ZUA1OToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NgogICAgLy8gY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB2ZXJpZnlfc3RyaW5nX2VuZHN3aXRoCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfc3RyaW5nX2pvaW5fcm91dGVANjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19qb2luCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfbG9nX3JvdXRlQDYxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozNTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2CiAgICAvLyBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDExCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgdmVyaWZ5X2xvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdANjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2luaXQocmF3X3ZhbHVlOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjctOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2luaXQoc2VsZiwgcmF3X3ZhbHVlOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjkKICAgIC8vIHJlc3VsdCA9IG9wLmJ0b2kocmF3X3ZhbHVlKQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfYWRkKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfYWRkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMi0xMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2FkZChzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE0CiAgICAvLyByZXN1bHQgPSBhICsgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICsKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9zdWIoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9zdWI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE3LTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV91aW50NjRfc3ViKHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTkKICAgIC8vIHJlc3VsdCA9IGEgLSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgLQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X211bChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X211bDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjItMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3VpbnQ2NF9tdWwoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gcmVzdWx0ID0gYSAqIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfZGl2KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfZGl2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNy0yOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2RpdihzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI5CiAgICAvLyByZXN1bHQgPSBhIC8vIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbW9kKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbW9kOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMi0zMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X21vZChzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM0CiAgICAvLyByZXN1bHQgPSBhICUgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9hbmQoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9hbmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM3LTM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV91aW50NjRfYW5kKHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzkKICAgIC8vIHJlc3VsdCA9IGEgJiBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgJgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo0MAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X29yKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfb3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjQyLTQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV91aW50NjRfb3Ioc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo0NAogICAgLy8gcmVzdWx0ID0gYSB8IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICB8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjQ1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfeG9yKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfeG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo0Ny00OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X3hvcihzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyByZXN1bHQgPSBhIF4gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIF4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NTAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9ub3QoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbm90OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1Mi01MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X25vdChzZWxmLCBhOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1NAogICAgLy8gcmVzdWx0ID0gfmEKICAgIGZyYW1lX2RpZyAtMQogICAgfgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1NQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2xzaGlmdChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2xzaGlmdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NTctNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3VpbnQ2NF9sc2hpZnQoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo1OQogICAgLy8gcmVzdWx0ID0gYSA8PCBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2hsCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfcnNoaWZ0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfcnNoaWZ0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo2Mi02MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X3JzaGlmdChzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjY0CiAgICAvLyByZXN1bHQgPSBhID4+IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NjUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9wb3coYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9wb3c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjY3LTY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV91aW50NjRfcG93KHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NjkKICAgIC8vIHJlc3VsdCA9IGEqKmIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NzAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9lcShhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo3Mi03MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2VxKHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojc0CiAgICAvLyByZXN1bHQgPSBhID09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo3NQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X25lKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV91aW50NjRfbmUoc2VsZiwgYTogVUludDY0LCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6NzkKICAgIC8vIHJlc3VsdCA9IGEgIT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjgwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbHQoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9sdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6ODItODMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3VpbnQ2NF9sdChzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo4NAogICAgLy8gcmVzdWx0ID0gYSA8IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojg1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbGUoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6ODctODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3VpbnQ2NF9sZShzZWxmLCBhOiBVSW50NjQsIGI6IFVJbnQ2NCkgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo4OQogICAgLy8gcmVzdWx0ID0gYSA8PSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPD0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6OTAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9ndChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo5Mi05MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2d0KHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojk0CiAgICAvLyByZXN1bHQgPSBhID4gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6OTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9nZShhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTo5Ny05OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfdWludDY0X2dlKHNlbGYsIGE6IFVJbnQ2NCwgYjogVUludDY0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5Ojk5CiAgICAvLyByZXN1bHQgPSBhID49IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA+PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMDAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2luaXQocmF3X3ZhbHVlOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZXNfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTAyLTEwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnl0ZXNfaW5pdChzZWxmLCByYXdfdmFsdWU6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTA0CiAgICAvLyByZXN1bHQgPSBvcC5pdG9iKHJhd192YWx1ZSkKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMDUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2FkZChhOiBieXRlcywgYjogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCwgcGFkX2Jfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTA3LTExMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnl0ZXNfYWRkKAogICAgLy8gICAgIHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcywgcGFkX2Ffc2l6ZTogVUludDY0LCBwYWRfYl9zaXplOiBVSW50NjQKICAgIC8vICkgLT4gQnl0ZXM6CiAgICBwcm90byA0IDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTExCiAgICAvLyBhID0gb3AuYnplcm8ocGFkX2Ffc2l6ZSkgKyBhCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSAtNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMTIKICAgIC8vIGIgPSBvcC5iemVybyhwYWRfYl9zaXplKSArIGIKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IC0zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjExMwogICAgLy8gcmVzdWx0ID0gYSArIGIKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTE0CiAgICAvLyByZXN1bHQgPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjExNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZXNfZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlc19lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTE3LTExOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYnl0ZXNfZXEoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjExOQogICAgLy8gcmVzdWx0ID0gYSA9PSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTIwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVzX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMjItMTIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9ieXRlc19uZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTI0CiAgICAvLyByZXN1bHQgPSBhICE9IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMjUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2FuZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZXNfYW5kOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMjctMTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9ieXRlc19hbmQoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxMjkKICAgIC8vIHJlc3VsdCA9IGEgJiBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYiYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTMwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19vcihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZXNfb3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzMi0xMzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2J5dGVzX29yKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTM0CiAgICAvLyByZXN1bHQgPSBhIHwgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZXNfeG9yKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc194b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzNy0xMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2J5dGVzX3hvcihzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjEzOQogICAgLy8gcmVzdWx0ID0gYSBeIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiXgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNDAKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX25vdChhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc19ub3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE0Mi0xNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2J5dGVzX25vdChzZWxmLCBhOiBCeXRlcywgcGFkX3NpemU6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTQ0CiAgICAvLyBhID0gb3AuYnplcm8ocGFkX3NpemUpICsgYQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIGR1cAogICAgZnJhbWVfYnVyeSAtMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNDUKICAgIC8vIHJlc3VsdCA9IH5hCiAgICBifgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNDYKICAgIC8vIHJlc3VsdCA9IG9wLnNoYTI1NihyZXN1bHQpCiAgICBzaGEyNTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTQ3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9hZGQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE0OS0xNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfYWRkKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTUzCiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgKyBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiKwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNTQKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTU2LTE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9hZGRfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE1OQogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50ICsgYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGIrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE2MAogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9zdWIoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfc3ViOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNjItMTYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X3N1YihzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE2NgogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50IC0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYi0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTY3CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE2OS0xNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NChzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNzIKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCAtIGIKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgZnJhbWVfZGlnIC0yCiAgICBzd2FwCiAgICBiLQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNzMKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfbXVsKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X211bDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTc1LTE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9tdWwoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxNzkKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCAqIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE4MAogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9tdWxfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tdWxfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxODItMTgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X211bF91aW50NjQoc2VsZiwgYTogQnl0ZXMsIGI6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTg1CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgKiBiCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYioKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTg2CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2RpdihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9kaXY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE4OC0xODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfZGl2KHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTkyCiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgLy8gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYi8KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTkzCiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjE5NS0xOTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NChzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToxOTgKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCAvLyBiCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgc3dhcAogICAgYi8KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MTk5CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X21vZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tb2Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIwMS0yMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfbW9kKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjA1CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgJSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiJQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMDYKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjA4LTIwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9tb2RfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIxMQogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50ICUgYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGIlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIxMgogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9hbmQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfYW5kOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMTQtMjE1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X2FuZChzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIxOAogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50ICYgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYiYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjE5CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIyMS0yMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NChzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMjQKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCAmIGIKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgZnJhbWVfZGlnIC0yCiAgICBiJgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMjUKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfb3IoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfb3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIyNy0yMjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfb3Ioc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBCeXRlczoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyMzEKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCB8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjIzMgogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9vcl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjM0LTIzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9vcl91aW50NjQoc2VsZiwgYTogQnl0ZXMsIGI6IFVJbnQ2NCkgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjM3CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgfCBiCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjM4CiAgICAvLyByZXR1cm4gcmVzdWx0LmJ5dGVzCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3hvcihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF94b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI0MC0yNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfeG9yKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjQ0CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgXiBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiXgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNDUKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfeG9yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfeG9yX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjQ3LTI0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF94b3JfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI1MAogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50IF4gYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI1MQogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI1My0yNTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfZXEoc2VsZiwgYTogQnl0ZXMsIGI6IEJ5dGVzKSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI1NwogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50ID09IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGI9PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNTgKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNjAtMjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NChzZWxmLCBhOiBCeXRlcywgYjogVUludDY0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI2MwogICAgLy8gcmVzdWx0ID0gYV9iaWd1aW50ID09IGIKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgZnJhbWVfZGlnIC0yCiAgICBiPT0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjY0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjY2LTI2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9uZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjcwCiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgIT0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYiE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9uZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9uZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI3My0yNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjc2CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgIT0gYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGIhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNzcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyNzktMjgwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X2x0KHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weToyODMKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCA8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGI8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI4NAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sdF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI4Ni0yODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjg5CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPCBiCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYj4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjkwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MjkyLTI5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9sZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6Mjk2CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPD0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYjw9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI5NwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjI5OS0zMDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzAyCiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPD0gYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGI+PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMDMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMDUtMzA2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9iaWd1aW50X2d0KHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMDkKICAgIC8vIHJlc3VsdCA9IGFfYmlndWludCA+IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGI+CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMxMAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9ndF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9ndF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMxMi0zMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzE1CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPiBiCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYjwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzE2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzE4LTMxOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYmlndWludF9nZShzZWxmLCBhOiBCeXRlcywgYjogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzIyCiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPj0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYj49CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMyMwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9nZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMyNS0zMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzI4CiAgICAvLyByZXN1bHQgPSBhX2JpZ3VpbnQgPj0gYgogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIGI8PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMjkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19pbml0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3N0cmluZ19pbml0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMzEtMzMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB2ZXJpZnlfc3RyaW5nX2luaXQoc2VsZiwgYTogU3RyaW5nKSAtPiBTdHJpbmc6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzMzCiAgICAvLyByZXN1bHQgPSBTdHJpbmcoIkhlbGxvLCAiKSArIGEKICAgIGJ5dGUgIkhlbGxvLCAiCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMzQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19zdGFydHN3aXRoKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfc3RyaW5nX3N0YXJ0c3dpdGg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMzNi0zMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aChzZWxmLCBhOiBTdHJpbmcsIGI6IFN0cmluZykgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozMzgKICAgIC8vIHJlc3VsdCA9IGEuc3RhcnRzd2l0aChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGR1cAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgID4KICAgIGJ6IHZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aF90ZXJuYXJ5X2ZhbHNlQDIKICAgIGludCAwCiAgICBiIHZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aF90ZXJuYXJ5X21lcmdlQDMKCnZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aF90ZXJuYXJ5X2ZhbHNlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMzOAogICAgLy8gcmVzdWx0ID0gYS5zdGFydHN3aXRoKGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAwCiAgICBmcmFtZV9kaWcgMAogICAgZXh0cmFjdDMKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KCnZlcmlmeV9zdHJpbmdfc3RhcnRzd2l0aF90ZXJuYXJ5X21lcmdlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjMzOQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgc3dhcAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlByaW1pdGl2ZU9wcy5jb250cmFjdC5QcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2VuZHN3aXRoKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfc3RyaW5nX2VuZHN3aXRoOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozNDEtMzQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB2ZXJpZnlfc3RyaW5nX2VuZHN3aXRoKHNlbGYsIGE6IFN0cmluZywgYjogU3RyaW5nKSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM0MwogICAgLy8gcmVzdWx0ID0gYS5lbmRzd2l0aChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGR1cAogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGR1cAogICAgY292ZXIgMgogICAgPgogICAgYnogdmVyaWZ5X3N0cmluZ19lbmRzd2l0aF90ZXJuYXJ5X2ZhbHNlQDIKICAgIGludCAwCiAgICBiIHZlcmlmeV9zdHJpbmdfZW5kc3dpdGhfdGVybmFyeV9tZXJnZUAzCgp2ZXJpZnlfc3RyaW5nX2VuZHN3aXRoX3Rlcm5hcnlfZmFsc2VAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQzCiAgICAvLyByZXN1bHQgPSBhLmVuZHN3aXRoKGIpCiAgICBmcmFtZV9kaWcgMQogICAgZnJhbWVfZGlnIDAKICAgIGR1cAogICAgY292ZXIgMgogICAgLQogICAgZnJhbWVfZGlnIC0yCiAgICBzd2FwCiAgICB1bmNvdmVyIDIKICAgIGV4dHJhY3QzCiAgICBmcmFtZV9kaWcgLTEKICAgID09Cgp2ZXJpZnlfc3RyaW5nX2VuZHN3aXRoX3Rlcm5hcnlfbWVyZ2VAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQ0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19qb2luKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfam9pbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQ2LTM0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgdmVyaWZ5X3N0cmluZ19qb2luKHNlbGYsIGE6IFN0cmluZywgYjogU3RyaW5nKSAtPiBTdHJpbmc6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9QcmltaXRpdmVPcHMvY29udHJhY3QucHk6MzQ4CiAgICAvLyByZXN1bHQgPSBTdHJpbmcoIiwgIikuam9pbigoYSwgYikpCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ5dGUgIiwgIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1ByaW1pdGl2ZU9wcy9jb250cmFjdC5weTozNDkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5QcmltaXRpdmVPcHMuY29udHJhY3QuUHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2xvZyhhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcywgZDogYnl0ZXMsIGU6IGJ5dGVzLCBmOiBieXRlcywgZzogYnl0ZXMsIGg6IGJ5dGVzLCBpOiBieXRlcywgajogYnl0ZXMsIGs6IGJ5dGVzLCBtOiBieXRlcywgbjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM1MS0zNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHZlcmlmeV9sb2coICAjIG5vcWE6IFBMUjA5MTMKICAgIC8vICAgICBzZWxmLAogICAgLy8gICAgIGE6IFN0cmluZywKICAgIC8vICAgICBiOiBVSW50NjQsCiAgICAvLyAgICAgYzogQnl0ZXMsCiAgICAvLyAgICAgZDogQnl0ZXMsCiAgICAvLyAgICAgZTogYXJjNC5Cb29sLAogICAgLy8gICAgIGY6IGFyYzQuU3RyaW5nLAogICAgLy8gICAgIGc6IGFyYzQuVUludE5bdHlwaW5nLkxpdGVyYWxbNjRdXSwKICAgIC8vICAgICBoOiBhcmM0LkJpZ1VJbnROW3R5cGluZy5MaXRlcmFsWzI1Nl1dLAogICAgLy8gICAgIGk6IGFyYzQuVUZpeGVkTnhNW3R5cGluZy5MaXRlcmFsWzMyXSwgdHlwaW5nLkxpdGVyYWxbOF1dLAogICAgLy8gICAgIGo6IGFyYzQuQmlnVUZpeGVkTnhNW3R5cGluZy5MaXRlcmFsWzI1Nl0sIHR5cGluZy5MaXRlcmFsWzE2XV0sCiAgICAvLyAgICAgazogQnl0ZXMsCiAgICAvLyAgICAgbTogQnl0ZXMsCiAgICAvLyAgICAgbjogQnl0ZXMsCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byAxMyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjM3MgogICAgLy8gbG9nKGEsIGIsIGMsIGRfYmlndWludCwgZSwgZiwgZywgaCwgaSwgaiwgYXJjNF9rLCBhcmM0X20sIGFyYzRfbiwgc2VwPSItIikKICAgIGZyYW1lX2RpZyAtMTMKICAgIGJ5dGUgIi0iCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMTIKICAgIGl0b2IKICAgIGNvbmNhdAogICAgYnl0ZSAiLSIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xMQogICAgY29uY2F0CiAgICBieXRlICItIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEwCiAgICBjb25jYXQKICAgIGJ5dGUgIi0iCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtOQogICAgY29uY2F0CiAgICBieXRlICItIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTgKICAgIGNvbmNhdAogICAgYnl0ZSAiLSIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC03CiAgICBjb25jYXQKICAgIGJ5dGUgIi0iCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtNgogICAgY29uY2F0CiAgICBieXRlICItIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTUKICAgIGNvbmNhdAogICAgYnl0ZSAiLSIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC00CiAgICBjb25jYXQKICAgIGJ5dGUgIi0iCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICBieXRlICItIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgYnl0ZSAiLSIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGxvZwogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuUHJpbWl0aXZlT3BzLmNvbnRyYWN0LlByaW1pdGl2ZU9wc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvUHJpbWl0aXZlT3BzL2NvbnRyYWN0LnB5OjYKICAgIC8vIGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUgMHgwMAogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OQogICAgcHVzaGJ5dGVzcyAweDcyNWM2OTJiIDB4MTczMTQ1NTkgMHg1M2YzNDg5MyAweDg4YzhiMjY5IDB4YTQ2NGI3YWIgMHg5YzhiMTFiOCAweDZmNDA2NTRlIDB4ZWM5YTI5NzQgMHhjNzkzNzA4ZiAweDdkZGI3NDk5IDB4YTIxYzQ0M2QgMHg2ZTdmYjIxMiAweGIwMDdmY2IwIDB4MmViYzIwZDQgMHhiMDk1NGI2NiAweGRkMTQwYWVmIDB4YWNlNDc0ZGEgMHhiYTY5NDk5MCAweDZkYjU4MWMwIDB4OTFjOGRiODkgMHhkYmU3NzE1OCAweDlhMGYyMmUxIDB4NjQwMzNkMzcgMHgyYTcyMzdjNSAweGUzYTk0NDU4IDB4NDJmODdmN2QgMHgyYjU1NDJhNCAweDliZTJmYmU5IDB4MWNkOTI1MTUgMHg2NGUxNzA1YyAweGYxMjcxYzUwIDB4MmFiNjNiNzAgMHg4MzRiYjdkMiAweDUzMTYyMGQ3IDB4M2ZiOWU3NjkgMHhmYThkYjBiYyAweGE3MmVhNDg1IDB4YjdiMGJhMTkgMHg3NDQ2MGM0MiAweGFiMzIwNzM4IDB4NTJhZDQ2NTQgMHgxMDE1NjM5OSAweDBmMDc1OTU3IDB4YmQ4NDNkZmYgMHhiMzc3ZDM4MSAweDg5NzY3MjY1IDB4NDU2YjRiMjMgMHgzM2QxYjg4YyAweDZiZjk3M2VhIDB4NjdjZDZiYjIgMHgzZjU4ODA1YSAweDFlMTMwMDM5IDB4NTA5ZGM5MWQgMHhhNTY0YTIwMiAweDIzNjUwNzYzIC8vIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9pbml0KGJ5dGVbXSl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfYWRkKHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X3N1Yih1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9tdWwodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfZGl2KHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X21vZCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9hbmQodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfb3IodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfeG9yKHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X25vdCh1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2xzaGlmdCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9yc2hpZnQodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfcG93KHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2VxKHVpbnQ2NCx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9uZSh1aW50NjQsdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50NjRfbHQodWludDY0LHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2xlKHVpbnQ2NCx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9ndCh1aW50NjQsdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50NjRfZ2UodWludDY0LHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfaW5pdCh1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfYWRkKGJ5dGVbXSxieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9ieXRlc19lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlc19uZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlc19hbmQoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9ieXRlc19vcihieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX3hvcihieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX25vdChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfYWRkKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9hZGRfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9zdWIoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X211bChieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZGl2KGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9kaXZfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9tb2QoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X21vZF91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2FuZChieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfb3IoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfeG9yKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF94b3JfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbHQoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9sdF91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2xlX3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2d0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9nZV91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9pbml0X3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9hZGRfcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X3N1Yl9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbXVsX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9kaXZfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X21vZF9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYW5kX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9vcl9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfeG9yX3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbm90X3JvdXRlQDExIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbHNoaWZ0X3JvdXRlQDEyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfcnNoaWZ0X3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfcG93X3JvdXRlQDE0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZXFfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9uZV9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2x0X3JvdXRlQDE3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbGVfcm91dGVAMTggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9ndF9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2dlX3JvdXRlQDIwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19pbml0X3JvdXRlQDIxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19hZGRfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2VxX3JvdXRlQDIzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19uZV9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfYW5kX3JvdXRlQDI1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19vcl9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfeG9yX3JvdXRlQDI3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19ub3Rfcm91dGVAMjggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYWRkX3JvdXRlQDI5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2FkZF91aW50NjRfcm91dGVAMzAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfc3ViX3JvdXRlQDMxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjRfcm91dGVAMzIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbXVsX3JvdXRlQDMzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X211bF91aW50NjRfcm91dGVAMzQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZGl2X3JvdXRlQDM1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjRfcm91dGVAMzYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbW9kX3JvdXRlQDM3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X21vZF91aW50NjRfcm91dGVAMzggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYW5kX3JvdXRlQDM5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2FuZF91aW50NjRfcm91dGVANDAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfb3Jfcm91dGVANDEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfb3JfdWludDY0X3JvdXRlQDQyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3hvcl9yb3V0ZUA0MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF94b3JfdWludDY0X3JvdXRlQDQ0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2VxX3JvdXRlQDQ1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NF9yb3V0ZUA0NiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9uZV9yb3V0ZUA0NyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9uZV91aW50NjRfcm91dGVANDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbHRfcm91dGVANDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0X3JvdXRlQDUwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2xlX3JvdXRlQDUxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2xlX3VpbnQ2NF9yb3V0ZUA1MiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9ndF9yb3V0ZUA1MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9ndF91aW50NjRfcm91dGVANTQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ2Vfcm91dGVANTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0X3JvdXRlQDU2CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2luaXRfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2luaXQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYWRkX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfYWRkCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X3N1Yl9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X3N1YgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9tdWxfcm91dGVANToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9tdWwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZGl2X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfZGl2CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X21vZF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X21vZAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9hbmRfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9hbmQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfb3Jfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9vcgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF94b3Jfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfeG9yCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X25vdF9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9ub3QKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbHNoaWZ0X3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2xzaGlmdAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9yc2hpZnRfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfcnNoaWZ0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X3Bvd19yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9wb3cKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZXFfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X25lX3JvdXRlQDE2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9sdF9yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbGVfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZ3Rfcm91dGVAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZ2Vfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19pbml0X3JvdXRlQDIxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19pbml0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2FkZF9yb3V0ZUAyMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19hZGQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfZXFfcm91dGVAMjM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbmVfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfYW5kX3JvdXRlQDI1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2FuZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19vcl9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19vcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc194b3Jfcm91dGVAMjc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfeG9yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX25vdF9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX25vdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2FkZF9yb3V0ZUAyOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FkZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2FkZF91aW50NjRfcm91dGVAMzA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9zdWJfcm91dGVAMzE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9zdWIKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9zdWJfdWludDY0X3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9zdWJfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbXVsX3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbXVsCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NF9yb3V0ZUAzNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2Rpdl9yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2RpdgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjRfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9tb2Rfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tb2QKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9tb2RfdWludDY0X3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tb2RfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYW5kX3JvdXRlQDM5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfYW5kCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NF9yb3V0ZUA0MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X29yX3JvdXRlQDQxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfb3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9vcl91aW50NjRfcm91dGVANDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3hvcl9yb3V0ZUA0MzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X3hvcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3hvcl91aW50NjRfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9lcV9yb3V0ZUA0NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0X3JvdXRlQDQ2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9lcV91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9uZV9yb3V0ZUA0NzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0X3JvdXRlQDQ4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9uZV91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sdF9yb3V0ZUA0OToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0X3JvdXRlQDUwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sdF91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sZV9yb3V0ZUA1MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0X3JvdXRlQDUyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sZV91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9ndF9yb3V0ZUA1MzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0X3JvdXRlQDU0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9ndF91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9nZV9yb3V0ZUA1NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0X3JvdXRlQDU2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9nZV91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjMKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfaW5pdChyYXdfdmFsdWU6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NC01CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfaW5pdChyYXdfdmFsdWU6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5idG9pKHJhd192YWx1ZSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2FkZChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAtMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9hZGQoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyCiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgKyBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgKwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9zdWIoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9zdWI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2LTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfc3ViKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOAogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhIC0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIC0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbXVsKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbXVsOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMi0yMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X211bChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAqIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2RpdihhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2RpdjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgtMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9kaXYoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwCiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgLyBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgLwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9tb2QoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9tb2Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0LTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbW9kKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNgogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhICUgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfYW5kKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfYW5kOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MC00MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X2FuZChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAmIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAmCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X29yKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfb3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2LTQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfb3IoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4CiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgfCBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgfAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF94b3IoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF94b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUyLTUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfeG9yKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhIF4gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIF4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbm90KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X25vdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgtNTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9ub3QoYTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MAogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSB+YQogICAgZnJhbWVfZGlnIC0xCiAgICB+CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2xzaGlmdChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2xzaGlmdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjQtNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9sc2hpZnQoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2CiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgPDwgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNobAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9yc2hpZnQoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9yc2hpZnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcwLTcxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfcnNoaWZ0KGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3MgogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhID4+IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfcG93KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfcG93OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3Ni03NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X3BvdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAqKiBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXhwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2VxKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyLTgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfZXEoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NAogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA9PT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID09CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X25lKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg4LTg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbmUoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MAogICAgLy8gY29uc3QgcmVzdWx0ID0gYSAhPT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2x0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk0LTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbHQoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5NgogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA8IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2xlKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMC0xMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9sZShhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMgogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA8PSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPD0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2d0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNi0xMDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9ndChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOAogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA+IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA+CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9nZShhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTItMTEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfZ2UoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgPj0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID49CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2luaXQocmF3X3ZhbHVlOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZXNfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE4LTExOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfaW5pdChyYXdfdmFsdWU6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLml0b2IocmF3X3ZhbHVlKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2FkZChhOiBieXRlcywgYjogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCwgcGFkX2Jfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI0LTEyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfYWRkKGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byA0IDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX2Ffc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjcKICAgIC8vIGNvbnN0IHBhZGRlZEIgPSBvcC5iemVybyhwYWRfYl9zaXplKS5jb25jYXQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOAogICAgLy8gY29uc3QgcmVzdWx0ID0gcGFkZGVkQS5jb25jYXQocGFkZGVkQikKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjkKICAgIC8vIGNvbnN0IHJlc3VsdEhhc2ggPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMAogICAgLy8gcmV0dXJuIHJlc3VsdEhhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVzX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzMtMTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlc19lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzUKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgPT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVzX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzktMTQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlc19uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgIT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19hbmQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX2FuZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ1LTE0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfYW5kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEuYml0d2lzZUFuZChiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX29yKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc19vcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUxLTE1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfb3IoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MwogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5iaXR3aXNlT3IoYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc194b3IoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX3hvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3LTE1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfeG9yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTkKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEuYml0d2lzZVhvcihiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX25vdChhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc19ub3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2My0xNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVzX25vdChhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IHBhZGRlZEEuYml0d2lzZUludmVydCgpCiAgICBifgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjcKICAgIC8vIGNvbnN0IHJlc3VsdEhhc2ggPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OAogICAgLy8gcmV0dXJuIHJlc3VsdEhhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9hZGQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MS0xNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYWRkKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzUKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCArIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3NgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OS0xODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MgogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MwogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICsgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGIrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3N1YihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9zdWI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4Ny0xODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfc3ViKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTEKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAtIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGItCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NS0xOTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5OAogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5OQogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IC0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGItCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X211bChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tdWw6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMy0yMDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbXVsKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDcKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAqIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwOAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X211bF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X211bF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMS0yMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNAogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNQogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICogYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGIqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2RpdihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9kaXY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxOS0yMjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZGl2KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjMKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAvIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNy0yMjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMAogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMQogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IC8gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGIvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X21vZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tb2Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNS0yMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbW9kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzkKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAlIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X21vZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X21vZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0My0yNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NgogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NwogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICUgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGIlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FuZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9hbmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MS0yNTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYW5kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTUKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAmIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1NgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1OS0yNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MgogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MwogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICYgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X29yKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X29yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjctMjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X29yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzEKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCB8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfb3JfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzUtMjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3OAogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3OQogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IHwgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3hvcihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF94b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4My0yODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfeG9yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODcKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCBeIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MS0yOTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfeG9yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NAogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NQogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IF4gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk5LTMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDMKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA9PT0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYj09CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDctMzA4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEwCiAgICAvLyBjb25zdCByZXN1bHQgPSBhX2JpZ3VpbnQgPT09IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgZnJhbWVfZGlnIC0yCiAgICBiPT0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNC0zMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE4CiAgICAvLyBjb25zdCByZXN1bHQgPSBhX2JpZ3VpbnQgIT09IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIyLTMyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9uZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNQogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50ICE9PSBCaWdVaW50KGIpCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYiE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjktMzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMwogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50IDwgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYjwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sdF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNy0zMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDAKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBiPgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQ1LTM0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDkKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiPD0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1My0zNTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTYKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTcKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgYj49CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNjEtMzYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2NQogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50ID4gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYj4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9ndF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9ndF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2OS0zNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzIKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzMKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBiPAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc3LTM3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODEKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiPj0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzgyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9nZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4NS0zODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODgKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODkKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgYjw9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5MAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" }, "state": { "global": { @@ -1258,131 +1233,6 @@ "returns": { "type": "bool" } - }, - { - "name": "verify_string_init", - "args": [ - { - "type": "string", - "name": "a" - } - ], - "readonly": false, - "returns": { - "type": "string" - } - }, - { - "name": "verify_string_startswith", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "string", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_string_endswith", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "string", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "bool" - } - }, - { - "name": "verify_string_join", - "args": [ - { - "type": "string", - "name": "a" - }, - { - "type": "string", - "name": "b" - } - ], - "readonly": false, - "returns": { - "type": "string" - } - }, - { - "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": {} diff --git a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.clear.teal b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.clear.teal index 8341d36..c9f60d3 100644 --- a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.clear.teal +++ b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.PrimitiveOps.contract.PrimitiveOpsContract.clear_state_program: - // tests/artifacts/PrimitiveOps/contract.py:6 - // class PrimitiveOpsContract(ARC4Contract): - int 1 +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 82cf5e8..328cd36 100644 --- a/tests/artifacts/state-ops/contract.algo.ts +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -27,11 +27,11 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_balance(a: Account): uint64 { const [value, funded] = op.AcctParams.acctBalance(a) const [value_index, funded_index] = op.AcctParams.acctBalance(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') - assert(value == a.balance, 'expected Account balance to match') - assert(value == op.balance(a), 'expected op.balance to match') - assert(value == op.balance(get_1st_ref_index()), 'expected op.balance by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + assert(value === a.balance, 'expected Account balance to match') + assert(value === op.balance(a), 'expected op.balance to match') + assert(value === op.balance(get_1st_ref_index()), 'expected op.balance by index to match') return value } @@ -39,11 +39,11 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_min_balance(a: Account): uint64 { const [value, funded] = op.AcctParams.acctMinBalance(a) const [value_index, funded_index] = op.AcctParams.acctMinBalance(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') - assert(value == a.minBalance, 'expected Account min_balance to match') - assert(value == op.minBalance(a), 'expected op.min_balance to match') - assert(value == op.minBalance(get_1st_ref_index()), 'expected op.min_balance by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + assert(value === a.minBalance, 'expected Account min_balance to match') + assert(value === op.minBalance(a), 'expected op.min_balance to match') + assert(value === op.minBalance(get_1st_ref_index()), 'expected op.min_balance by index to match') return value } @@ -51,8 +51,8 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_auth_addr(a: Account): Account { const [value, funded] = op.AcctParams.acctAuthAddr(a) const [value_index, funded_index] = op.AcctParams.acctAuthAddr(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') // TODO: return arc4.Address(value) return value } @@ -61,8 +61,8 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_total_num_uint(a: Account): uint64 { const [value, funded] = op.AcctParams.acctTotalNumUint(a) const [value_index, funded_index] = op.AcctParams.acctTotalNumUint(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') return value } @@ -70,8 +70,8 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_total_num_byte_slice(a: Account): uint64 { const [value, funded] = op.AcctParams.acctTotalNumByteSlice(a) const [value_index, funded_index] = op.AcctParams.acctTotalNumByteSlice(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') return value } @@ -79,8 +79,8 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_total_extra_app_pages(a: Account): uint64 { const [value, funded] = op.AcctParams.acctTotalExtraAppPages(a) const [value_index, funded_index] = op.AcctParams.acctTotalExtraAppPages(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') return value } @@ -88,8 +88,8 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_total_apps_created(a: Account): uint64 { const [value, funded] = op.AcctParams.acctTotalAppsCreated(a) const [value_index, funded_index] = op.AcctParams.acctTotalAppsCreated(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') return value } @@ -97,8 +97,8 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_total_apps_opted_in(a: Account): uint64 { const [value, funded] = op.AcctParams.acctTotalAppsOptedIn(a) const [value_index, funded_index] = op.AcctParams.acctTotalAppsOptedIn(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') return value } @@ -106,8 +106,8 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_total_assets_created(a: Account): uint64 { const [value, funded] = op.AcctParams.acctTotalAssetsCreated(a) const [value_index, funded_index] = op.AcctParams.acctTotalAssetsCreated(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') return value } @@ -115,8 +115,8 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_total_assets(a: Account): uint64 { const [value, funded] = op.AcctParams.acctTotalAssets(a) const [value_index, funded_index] = op.AcctParams.acctTotalAssets(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') return value } @@ -124,8 +124,8 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_total_boxes(a: Account): uint64 { const [value, funded] = op.AcctParams.acctTotalBoxes(a) const [value_index, funded_index] = op.AcctParams.acctTotalBoxes(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') return value } @@ -133,8 +133,8 @@ export class StateAcctParamsGetContract extends arc4.Contract { public verify_acct_total_box_bytes(a: Account): uint64 { const [value, funded] = op.AcctParams.acctTotalBoxBytes(a) const [value_index, funded_index] = op.AcctParams.acctTotalBoxBytes(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(funded == funded_index, 'expected funded by index to match') + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') return value } } @@ -158,8 +158,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_total(a: Asset): uint64 { const [value, exists] = op.AssetParams.assetTotal(a) const [value_index, exists_index] = op.AssetParams.assetTotal(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -167,8 +167,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_decimals(a: Asset): uint64 { const [value, exists] = op.AssetParams.assetDecimals(a) const [value_index, exists_index] = op.AssetParams.assetDecimals(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -176,8 +176,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_default_frozen(a: Asset): boolean { const [value, exists] = op.AssetParams.assetDefaultFrozen(a) const [value_index, exists_index] = op.AssetParams.assetDefaultFrozen(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -185,8 +185,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_unit_name(a: Asset): bytes { const [value, exists] = op.AssetParams.assetUnitName(a) const [value_index, exists_index] = op.AssetParams.assetUnitName(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -194,8 +194,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_name(a: Asset): bytes { const [value, exists] = op.AssetParams.assetName(a) const [value_index, exists_index] = op.AssetParams.assetName(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -203,8 +203,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_url(a: Asset): bytes { const [value, exists] = op.AssetParams.assetUrl(a) const [value_index, exists_index] = op.AssetParams.assetUrl(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -212,8 +212,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_metadata_hash(a: Asset): bytes { const [value, exists] = op.AssetParams.assetMetadataHash(a) const [value_index, exists_index] = op.AssetParams.assetMetadataHash(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -221,8 +221,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_manager(a: Asset): Account { const [value, exists] = op.AssetParams.assetManager(a) const [value_index, exists_index] = op.AssetParams.assetManager(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') // TODO: return arc4.Address(value) return value } @@ -231,8 +231,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_reserve(a: Asset): Account { const [value, exists] = op.AssetParams.assetReserve(a) const [value_index, exists_index] = op.AssetParams.assetReserve(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') // TODO: return arc4.Address(value) return value } @@ -241,8 +241,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_freeze(a: Asset): Account { const [value, exists] = op.AssetParams.assetFreeze(a) const [value_index, exists_index] = op.AssetParams.assetFreeze(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') // TODO: return arc4.Address(value) return value } @@ -251,8 +251,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_clawback(a: Asset): Account { const [value, exists] = op.AssetParams.assetClawback(a) const [value_index, exists_index] = op.AssetParams.assetClawback(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') // TODO: return arc4.Address(value) return value } @@ -261,8 +261,8 @@ export class StateAssetParamsContract extends arc4.Contract { public verify_asset_params_get_creator(a: Asset): Account { const [value, exists] = op.AssetParams.assetCreator(a) const [value_index, exists_index] = op.AssetParams.assetCreator(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') // TODO: return arc4.Address(value) return value } @@ -273,8 +273,8 @@ export class StateAppParamsContract extends arc4.Contract { public verify_app_params_get_approval_program(a: Application): bytes { const [value, exists] = op.AppParams.appApprovalProgram(a) const [value_index, exists_index] = op.AppParams.appApprovalProgram(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -282,8 +282,8 @@ export class StateAppParamsContract extends arc4.Contract { public verify_app_params_get_clear_state_program(a: Application): bytes { const [value, exists] = op.AppParams.appClearStateProgram(a) const [value_index, exists_index] = op.AppParams.appClearStateProgram(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -291,8 +291,8 @@ export class StateAppParamsContract extends arc4.Contract { public verify_app_params_get_global_num_uint(a: Application): uint64 { const [value, exists] = op.AppParams.appGlobalNumUint(a) const [value_index, exists_index] = op.AppParams.appGlobalNumUint(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -300,8 +300,8 @@ export class StateAppParamsContract extends arc4.Contract { public verify_app_params_get_global_num_byte_slice(a: Application): uint64 { const [value, exists] = op.AppParams.appGlobalNumByteSlice(a) const [value_index, exists_index] = op.AppParams.appGlobalNumByteSlice(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -309,8 +309,8 @@ export class StateAppParamsContract extends arc4.Contract { public verify_app_params_get_local_num_uint(a: Application): uint64 { const [value, exists] = op.AppParams.appLocalNumUint(a) const [value_index, exists_index] = op.AppParams.appLocalNumUint(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -318,8 +318,8 @@ export class StateAppParamsContract extends arc4.Contract { public verify_app_params_get_local_num_byte_slice(a: Application): uint64 { const [value, exists] = op.AppParams.appLocalNumByteSlice(a) const [value_index, exists_index] = op.AppParams.appLocalNumByteSlice(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -327,8 +327,8 @@ export class StateAppParamsContract extends arc4.Contract { public verify_app_params_get_extra_program_pages(a: Application): uint64 { const [value, exists] = op.AppParams.appExtraProgramPages(a) const [value_index, exists_index] = op.AppParams.appExtraProgramPages(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') return value } @@ -336,8 +336,8 @@ export class StateAppParamsContract extends arc4.Contract { public verify_app_params_get_creator(a: Application): Account { const [value, exists] = op.AppParams.appCreator(a) const [value_index, exists_index] = op.AppParams.appCreator(get_1st_ref_index()) - assert(value == value_index, 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value === value_index, 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') // TODO: return arc4.Address(value) return value } @@ -347,8 +347,8 @@ export class StateAppParamsContract extends arc4.Contract { const [value, exists] = op.AppParams.appAddress(a) const [value_index, exists_index] = op.AppParams.appAddress(get_1st_ref_index()) // TODO: recompile when puya ts is ready - assert(value.bytes.toString() == value_index.bytes.toString(), 'expected value by index to match') - assert(exists == exists_index, 'expected exists by index to match') + assert(value.bytes.toString() === value_index.bytes.toString(), 'expected value by index to match') + assert(exists === exists_index, 'expected exists by index to match') // TODO: return arc4.Address(value) return value } @@ -500,8 +500,8 @@ export class ITxnOpsContract extends arc4.Contract { assert(op.ITxn.amount === Uint64(1000)) assert(op.ITxn.typeEnum === TransactionType.Payment) - assert(op.GITxn.typeEnum(0) == TransactionType.ApplicationCall) - assert(op.GITxn.typeEnum(1) == TransactionType.Payment) + assert(op.GITxn.typeEnum(0) === TransactionType.ApplicationCall) + assert(op.GITxn.typeEnum(1) === TransactionType.Payment) } } @@ -599,3 +599,6 @@ export class ItxnDemoContract extends BaseContract { assert(createAppTxn.note === Bytes('with args param set')) } } + +// TODO: add GlobalStateContract when arc4 types are ready +// TODO: add LocalStateContract when arc4 types are ready diff --git a/tests/primitives/biguint.spec.ts b/tests/primitives/biguint.spec.ts index 894d268..efbee2a 100644 --- a/tests/primitives/biguint.spec.ts +++ b/tests/primitives/biguint.spec.ts @@ -5,6 +5,7 @@ import type { biguint } from '@algorandfoundation/algorand-typescript' import { BigUint, Bytes, internal, Uint64 } from '@algorandfoundation/algorand-typescript' import { describe, expect, it } from 'vitest' import { BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE, MAX_UINT512, MAX_UINT64 } from '../../src/constants' +import { asUint64 } from '../../src/util' import appSpecJson from '../artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' import { abiAsBytes } from '../util' @@ -238,6 +239,35 @@ describe('BigUint', async () => { }) }) + describe.each([ + [0n, 0n], + [0n, MAX_UINT64], + [MAX_UINT512, 0n], + [1n, 0n], + [0n, 1n], + [1n, 1n], + [10n, MAX_UINT64], + [MAX_UINT512 - MAX_UINT64, MAX_UINT64], + ])('biguint addition with uint64', async (a, b) => { + it(`${a} + ${b}`, async () => { + const bigUintA = BigUint(a) + const uint64B = Uint64(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_add_uint64', bytesA, b))) + + let result = bigUintA + BigUint(uint64B) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) + + result = BigUint(uint64B) + bigUintA + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) + + let i = bigUintA + i += BigUint(uint64B) + expect(i, `for values: ${a}, ${b}`).toEqual(avmResult) + }) + }) + describe.each([ [0n, 0n], [1n, 0n], @@ -310,6 +340,30 @@ describe('BigUint', async () => { }) }) + describe.each([ + [0n, 0n], + [1n, 0n], + [1n, 1n], + [MAX_UINT512, 0n], + [MAX_UINT512, 1n], + [MAX_UINT512, MAX_UINT64], + ])('biguint subtraction with uint64', async (a, b) => { + it(`${a} - ${b}`, async () => { + const bigUintA = BigUint(a) + const uint64B = Uint64(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_sub_uint64', bytesA, b))) + + const result = bigUintA - BigUint(uint64B) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) + + let i = BigUint(a) + i -= BigUint(b) + expect(i, `for values: ${a}, ${b}`).toEqual(avmResult) + }) + }) + describe.each([ [0, 0], [0, 1], @@ -395,6 +449,32 @@ describe('BigUint', async () => { }) }) + describe.each([ + [0n, 0n], + [0n, 1n], + [0n, MAX_UINT64], + [1n, MAX_UINT64], + [2n, MAX_UINT64], + ])(`biguint multiplication with uint64`, async (a, b) => { + it(`${a} * ${b}`, async () => { + const bigUintA = asBigUint(a) + const uint64B = asUint64(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_mul_uint64', bytesA, b))) + + let result = bigUintA * BigUint(uint64B) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) + + result = BigUint(uint64B) * bigUintA + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) + + let i = bigUintA + i *= BigUint(uint64B) + expect(i, `for values: ${a}, ${b}`).toEqual(avmResult) + }) + }) + describe.each([ [MAX_UINT512, 1], [MAX_UINT512, 2], @@ -469,6 +549,30 @@ describe('BigUint', async () => { }) }) + describe.each([ + [MAX_UINT512, 1n], + [MAX_UINT512, 2n], + [MAX_UINT512, MAX_UINT64], + [0n, MAX_UINT64], + [1n, MAX_UINT64], + [3n, 2n], + ])('biguint division with uint64', async (a, b) => { + it(`${a} / ${b}`, async () => { + const bigUintA = asBigUint(a) + const uint64B = asUint64(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_div_uint64', bytesA, b))) + + const result = bigUintA / BigUint(uint64B) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) + + let i = BigUint(a) + i /= BigUint(uint64B) + expect(i, `for values: ${a}, ${b}`).toEqual(avmResult) + }) + }) + describe.each([ [MAX_UINT512, 1], [MAX_UINT512, 2], @@ -542,6 +646,29 @@ describe('BigUint', async () => { }) }) + describe.each([ + [MAX_UINT512, 1n], + [MAX_UINT512, 2n], + [MAX_UINT512, MAX_UINT64], + [0n, MAX_UINT64], + [1n, MAX_UINT64], + [3n, 2n], + ])('biguint modulo with uint64', async (a, b) => { + it(`${a} % ${b}`, async () => { + const bigUintA = asBigUint(a) + const uint64B = asUint64(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_mod_uint64', bytesA, b))) + const result = bigUintA % BigUint(uint64B) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) + + let i = BigUint(a) + i %= BigUint(uint64B) + expect(i, `for values: ${a}, ${b}`).toEqual(avmResult) + }) + }) + describe.each(['and', 'or', 'xor'])('bitwise operators', async (op) => { const operator = (function () { switch (op) { @@ -596,6 +723,24 @@ describe('BigUint', async () => { } }) }) + + describe.each([ + [0, 0], + [MAX_UINT512, MAX_UINT64], + [MAX_UINT512, 0], + [42, MAX_UINT64], + [MAX_UINT512, 42], + ])(`${operator} with uint64`, async (a, b) => { + const bigUintA = asBigUint(a) + const uint64B = asUint64(b) + const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) + + it(`${a} ${operator} ${b}`, async () => { + const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, `verify_biguint_${op}_uint64`, bytesA, b))) + const result = getStubResult(bigUintA, BigUint(uint64B)) + expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) + }) + }) }) describe.each([MAX_UINT512 + 1n, MAX_UINT512 * 2n])('value too big', (a) => { diff --git a/tests/pure-op-codes.spec.ts b/tests/pure-op-codes.spec.ts index 46b66d8..9f795c4 100644 --- a/tests/pure-op-codes.spec.ts +++ b/tests/pure-op-codes.spec.ts @@ -1,5 +1,5 @@ import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { Base64, BigUint, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { Base64, BigUint, bytes, Bytes, err, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' import { @@ -328,6 +328,13 @@ describe('Pure op codes', async () => { }) }) + describe('err', async () => { + it('should throw default error', async () => { + await expect(getAvmResultRaw({ appClient }, 'verify_err')).rejects.toThrow('err opcode executed') + expect(() => err()).toThrow('err opcode executed') + }) + }) + describe('exp', async () => { test.each([ [0, 1], @@ -427,7 +434,7 @@ describe('Pure op codes', async () => { } }) - test.each(['hello, world', 'hi'])('should work to extract bytes from 2 to end', async (a) => { + test.each(['hello, world', 'hi'])('should work to extract bytes from 2 to end for %s', async (a) => { const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_extract_from_2', asUint8Array(a)))! const result = op.extract(a, 2, 0) expect(result).toEqual(avmResult) From 84e4e349b1e821ef525c8b036a273dd5169e9925 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 7 Nov 2024 12:24:29 +0800 Subject: [PATCH 49/85] fix: runtime-helper does not truly handles augmented assignment so strip `=` sign from operator before calling it --- src/runtime-helpers.ts | 43 +--------------------------- src/test-transformer/node-factory.ts | 2 +- 2 files changed, 2 insertions(+), 43 deletions(-) diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index ed5968a..271d844 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -20,30 +20,7 @@ export function switchableValue(x: unknown): bigint | string | boolean { // internalError(`Cannot wrap ${nameOfType(x)}`) // } -type BinaryOps = - | '+' - | '-' - | '*' - | '**' - | '/' - | '%' - | '>' - | '>=' - | '<' - | '<=' - | '===' - | '!==' - | '<<' - | '>>' - | '&' - | '|' - | '^' - | '+=' - | '-=' - | '/=' - | '*=' - | '**=' - | '%=' +type BinaryOps = '+' | '-' | '*' | '**' | '/' | '%' | '>' | '>=' | '<' | '<=' | '===' | '!==' | '<<' | '>>' | '&' | '|' | '^' type UnaryOps = '~' function tryGetBigInt(value: unknown): bigint | undefined { @@ -95,25 +72,19 @@ function uint64BinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps const result = (function () { switch (op) { case '+': - case '+=': return lbi + rbi case '-': - case '-=': return lbi - rbi case '*': - case '*=': return lbi * rbi case '**': - case '**=': if (lbi === 0n && rbi === 0n) { throw internal.errors.codeError('0 ** 0 is undefined') } return lbi ** rbi case '/': - case '/=': return lbi / rbi case '%': - case '%=': return lbi % rbi case '>>': if (rbi > 63n) { @@ -156,25 +127,19 @@ function bigUintBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOp const result = (function () { switch (op) { case '+': - case '+=': return lbi + rbi case '-': - case '-=': return lbi - rbi case '*': - case '*=': return lbi * rbi case '**': - case '**=': if (lbi === 0n && rbi === 0n) { throw internal.errors.codeError('0 ** 0 is undefined') } return lbi ** rbi case '/': - case '/=': return lbi / rbi case '%': - case '%=': return lbi % rbi case '>>': throw new internal.errors.CodeError('BigUint does not support >> operator') @@ -242,25 +207,19 @@ function bytesBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps) function defaultBinaryOp(left: DeliberateAny, right: DeliberateAny, op: BinaryOps): DeliberateAny { switch (op) { case '+': - case '+=': return left + right case '-': - case '-=': return left - right case '*': - case '*=': return left * right case '**': - case '**=': if (left === 0n && right === 0n) { throw new internal.errors.CodeError('0 ** 0 is undefined') } return left ** right case '/': - case '/=': return left / right case '%': - case '%=': return left % right case '>>': if (typeof left === 'bigint' && typeof right === 'bigint') { diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index bff7076..7f336ee 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -34,7 +34,7 @@ export const nodeFactory = { factory.createCallExpression( factory.createPropertyAccessExpression(factory.createIdentifier('runtimeHelpers'), factory.createIdentifier('binaryOp')), undefined, - [left, right, factory.createStringLiteral(op)], + [left, right, factory.createStringLiteral(op.replace('=', ''))], ), ) }, From e5eeccf3cbaab3c4b7152b62332f0cbc093d19f6 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 12 Nov 2024 09:51:09 +0800 Subject: [PATCH 50/85] chore: upgrade algots package version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index fd89c92..5e52c02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.15", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.16", "@algorandfoundation/puya-ts": "^1.0.0-alpha.24", "algosdk": "^2.9.0", "elliptic": "^6.5.7", @@ -73,9 +73,9 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.15", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.15.tgz", - "integrity": "sha512-iIKBVO6dNz1F2acD6ymhbe4gNIDywZAR7vKxPq5BV7aZoS/mtJkur9oTniyDTAfBZl5JqY3qNDuJUlGZa9K/9w==", + "version": "0.0.1-alpha.16", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.16.tgz", + "integrity": "sha512-6X9PccsvbE8v6rVB1QVdjYaYIAHbBXived1K0SD+YeHwd/cCjfsetEZGqWF1q3WO4jiID72ViVb5FYOvj5N5uQ==", "peerDependencies": { "tslib": "^2.6.2" } diff --git a/package.json b/package.json index 74f4fcb..0c403f2 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ }, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.15", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.16", "@algorandfoundation/puya-ts": "^1.0.0-alpha.24", "algosdk": "^2.9.0", "elliptic": "^6.5.7", From 6b91d41b87b4538544eabf7fc4a317354ca62334 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 12 Nov 2024 11:05:53 +0800 Subject: [PATCH 51/85] refactor: generic type info capture as PType has been changed in puya-ts --- package-lock.json | 8 +- package.json | 2 +- src/test-transformer/visitors.ts | 164 ++++++++++++++++++++++++------- src/typescript-helpers.ts | 7 ++ 4 files changed, 140 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5e52c02..c66ecd9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.16", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.24", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.26", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", @@ -81,9 +81,9 @@ } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0-alpha.24", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.24.tgz", - "integrity": "sha512-5nSf2eULkenlGhPWXMgTXZ+F95d81Pck1809F1ndCCBKUd3M+0RopC1IBFpWJcIJZCxsK9LTPJySLxoc+2bmIQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0.tgz", + "integrity": "sha512-8oh95rg9sV3xy3L0tuynlW9phhT7NO1NTiD2vq+iv8n7lXmoBWwenagNEePZSmfUOOjdJfim0cKb+BOXYG9Udg==", "bundleDependencies": [ "typescript" ], diff --git a/package.json b/package.json index 0c403f2..e1919e3 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.16", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.24", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.26", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index fdf40e3..fa8fee2 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -1,7 +1,24 @@ -import { anyPType, ContractClassPType, FunctionPType, PType, SourceLocation, typeRegistry, TypeResolver } from '@algorandfoundation/puya-ts' +import { + anyPType, + ARC4StructType, + ARC4TupleType, + BoxMapPType, + BoxPType, + ContractClassPType, + DynamicArrayType, + FunctionPType, + GlobalStateType, + LocalStateType, + PType, + SourceLocation, + StaticArrayType, + TypeResolver, + UFixedNxMType, + UintNType, +} from '@algorandfoundation/puya-ts' import ts from 'typescript' import type { TypeInfo } from '../encoders' -import { DeliberateAny } from '../typescript-helpers' +import { instanceOfAny } from '../typescript-helpers' import { TransformerConfig } from './index' import { nodeFactory } from './node-factory' import { @@ -61,9 +78,64 @@ export class SourceFileVisitor { return new ClassVisitor(this.context, this.helper, node).result() } + // capture generic type info for variable initialising outside class and function declarations + // e.g. `const x = new UintN<32>(42) + if (ts.isVariableDeclaration(node) && node.initializer) { + return new VariableInitializerVisitor(this.context, this.helper, node).result() + } + + return ts.visitEachChild(node, this.visit, this.context) + } +} + +class ExpressionVisitor { + constructor( + private context: ts.TransformationContext, + private helper: VisitorHelper, + private expressionNode: ts.Expression, + ) {} + + public result(): ts.Expression { + return this.visit(this.expressionNode) as ts.Expression + } + + private visit = (node: ts.Node): ts.Node => { + if (ts.isCallExpression(node) || ts.isNewExpression(node)) { + let type = this.helper.resolveType(node) + + // `voted = LocalState()` is resolved to FunctionPType with returnType LocalState + if (type instanceof FunctionPType) type = type.returnType + + if (isGenericType(type)) { + const info = getGenericTypeInfo(type) + return nodeFactory.captureGenericTypeInfo(ts.visitEachChild(node, this.visit, this.context), JSON.stringify(info)) + } + } return ts.visitEachChild(node, this.visit, this.context) } } +class VariableInitializerVisitor { + constructor( + private context: ts.TransformationContext, + private helper: VisitorHelper, + private declarationNode: ts.VariableDeclaration, + ) {} + + public result(): ts.VariableDeclaration { + const initializerNode = this.declarationNode.initializer + if (!initializerNode) return this.declarationNode + + const updatedInitializer = new ExpressionVisitor(this.context, this.helper, initializerNode).result() + if (updatedInitializer === initializerNode) return this.declarationNode + return factory.updateVariableDeclaration( + this.declarationNode, + this.declarationNode.name, + this.declarationNode.exclamationToken, + this.declarationNode.type, + updatedInitializer, + ) + } +} class FunctionOrMethodVisitor { constructor( @@ -110,17 +182,20 @@ class FunctionOrMethodVisitor { * }) * ``` */ - if (this.isFunction && ts.isVariableDeclaration(node) && node.initializer && ts.isCallExpression(node.initializer)) { - const initializerNode = node.initializer - let type = this.helper.resolveType(initializerNode) + if (this.isFunction && ts.isVariableDeclaration(node) && node.initializer) { + return new VariableInitializerVisitor(this.context, this.helper, node).result() + } - // `voted = LocalState()` is resolved to FunctionPType with returnType LocalState - if (type instanceof FunctionPType) type = type.returnType - if (typeRegistry.isGeneric(type)) { - const info = getGenericTypeInfo(type) - const updatedInitializer = nodeFactory.captureGenericTypeInfo(initializerNode, JSON.stringify(info)) - return factory.updateVariableDeclaration(node, node.name, node.exclamationToken, node.type, updatedInitializer) - } + /* + * capture generic type info in test functions and swap arc4 types with implementation; e.g. + * ``` + * it('should work', () => { + * expect(() => new UintN<32>(2 ** 32)).toThrowError(`expected value <= ${2 ** 32 - 1}`) + * }) + * ``` + */ + if (this.isFunction && ts.isNewExpression(node)) { + return new ExpressionVisitor(this.context, this.helper, node).result() } return node } @@ -181,38 +256,55 @@ class ClassVisitor { } if (ts.isCallExpression(node)) { - let type = this.helper.resolveType(node) - - // `voted = LocalState()` is resolved to FunctionPType with returnType LocalState - if (type instanceof FunctionPType) type = type.returnType - - if (typeRegistry.isGeneric(type)) { - const info = getGenericTypeInfo(type) - return nodeFactory.captureGenericTypeInfo(ts.visitEachChild(node, this.visit, this.context), JSON.stringify(info)) - } + return new ExpressionVisitor(this.context, this.helper, node).result() } return ts.visitEachChild(node, this.visit, this.context) } } +const isGenericType = (type: PType): boolean => + instanceOfAny( + type, + ARC4StructType, + ARC4TupleType, + BoxMapPType, + BoxPType, + DynamicArrayType, + GlobalStateType, + LocalStateType, + StaticArrayType, + UFixedNxMType, + UintNType, + ) + const getGenericTypeInfo = (type: PType): TypeInfo => { - let genericArgs: TypeInfo[] | Record | undefined = typeRegistry.isGeneric(type) - ? type.getGenericArgs().map(getGenericTypeInfo) - : undefined - - if (!genericArgs || !genericArgs.length) { - if (Object.hasOwn(type, 'items')) { - genericArgs = (type as DeliberateAny).items.map(getGenericTypeInfo) - } else if (Object.hasOwn(type, 'itemType')) { - genericArgs = [getGenericTypeInfo((type as DeliberateAny).itemType)] - } else if (Object.hasOwn(type, 'properties')) { - genericArgs = Object.fromEntries( - Object.entries((type as DeliberateAny).properties).map(([key, value]) => [key, getGenericTypeInfo(value as PType)]), - ) - } + const genericArgs: TypeInfo[] | Record = [] + + if (instanceOfAny(type, LocalStateType, GlobalStateType, BoxPType)) { + genericArgs.push(getGenericTypeInfo(type.contentType)) + } else if (type instanceof BoxMapPType) { + genericArgs.push(getGenericTypeInfo(type.keyType)) + genericArgs.push(getGenericTypeInfo(type.contentType)) + } else if (instanceOfAny(type, StaticArrayType, DynamicArrayType)) { + genericArgs.push(getGenericTypeInfo(type.elementType)) + } else if (type instanceof UFixedNxMType) { + genericArgs.push({ name: type.n.toString() }) + genericArgs.push({ name: type.m.toString() }) + } else if (type instanceof UintNType) { + genericArgs.push({ name: type.n.toString() }) + } else if (type instanceof ARC4StructType) { + genericArgs.push( + ...Object.fromEntries( + Object.entries(type.fields) + .map(([key, value]) => [key, getGenericTypeInfo(value)]) + .filter((x) => !!x), + ), + ) + } else if (type instanceof ARC4TupleType) { + genericArgs.push(...type.items.map(getGenericTypeInfo)) } - const result: TypeInfo = { name: type?.name ?? 'unknown' } + const result: TypeInfo = { name: type?.name ?? type?.toString() ?? 'unknown' } if (genericArgs && (genericArgs.length || Object.keys(genericArgs).length)) { result.genericArgs = genericArgs } diff --git a/src/typescript-helpers.ts b/src/typescript-helpers.ts index 9e03cc3..a7bd1b5 100644 --- a/src/typescript-helpers.ts +++ b/src/typescript-helpers.ts @@ -18,3 +18,10 @@ export type KeyIsNotFunction = TKey extends Delib : never export type ObjectKeys = KeyIsNotFunction export type FunctionKeys = KeyIsFunction + +export function instanceOfAny>( + x: unknown, + ...types: T +): x is InstanceType { + return types.some((t) => x instanceof t) +} From 8b2b59824a3b17cc48487f5b69a478b8d0673175 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 10 Dec 2024 14:26:24 +0800 Subject: [PATCH 52/85] refactor: add placeholders for v11 fields and methods --- src/impl/acct-params.ts | 10 ++++++++++ src/impl/block.ts | 29 +++++++++++++++++++++++++++-- src/impl/global.ts | 6 ++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/impl/acct-params.ts b/src/impl/acct-params.ts index 2893135..2864405 100644 --- a/src/impl/acct-params.ts +++ b/src/impl/acct-params.ts @@ -70,4 +70,14 @@ export const AcctParams: internal.opTypes.AcctParamsType = { 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.') + }, + acctLastProposed: function (_a: Account | uint64): readonly [uint64, boolean] { + throw new Error('Function not implemented.') + }, + acctLastHeartbeat: function (_a: Account | uint64): readonly [uint64, boolean] { + throw new Error('Function not implemented.') + }, } diff --git a/src/impl/block.ts b/src/impl/block.ts index 0d232bf..79e9069 100644 --- a/src/impl/block.ts +++ b/src/impl/block.ts @@ -1,7 +1,7 @@ -import { bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { itob } from './pure' import { asUint64 } from '../util' +import { itob } from './pure' export const Block: internal.opTypes.BlockType = { blkSeed: function (a: internal.primitives.StubUint64Compat): bytes { @@ -10,4 +10,29 @@ export const Block: internal.opTypes.BlockType = { blkTimestamp: function (a: internal.primitives.StubUint64Compat): uint64 { return asUint64(lazyContext.ledger.getBlockContent(a).timestamp) }, + // TODO: implement v11 methods + blkProposer: function (_a: uint64): Account { + throw new Error('Function not implemented.') + }, + blkFeesCollected: function (_a: uint64): uint64 { + throw new Error('Function not implemented.') + }, + blkBonus: function (_a: uint64): uint64 { + throw new Error('Function not implemented.') + }, + blkBranch: function (_a: uint64): bytes { + throw new Error('Function not implemented.') + }, + blkFeeSink: function (_a: uint64): Account { + throw new Error('Function not implemented.') + }, + blkProtocol: function (_a: uint64): bytes { + throw new Error('Function not implemented.') + }, + blkTxnCounter: function (_a: uint64): uint64 { + throw new Error('Function not implemented.') + }, + blkProposerPayout: function (_a: uint64): uint64 { + throw new Error('Function not implemented.') + }, } diff --git a/src/impl/global.ts b/src/impl/global.ts index 41ed7a5..06921dc 100644 --- a/src/impl/global.ts +++ b/src/impl/global.ts @@ -187,4 +187,10 @@ 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, } From 9a42d8d66056d0b56f568f1081aa08726bd9d157 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 12 Dec 2024 10:08:59 +0800 Subject: [PATCH 53/85] chore: upgrade algorand-typescript and puya-ts package versions --- package-lock.json | 626 ++++++++++++---------------------------------- package.json | 8 +- 2 files changed, 160 insertions(+), 474 deletions(-) diff --git a/package-lock.json b/package-lock.json index c66ecd9..358304a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,8 @@ "hasInstallScript": true, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.16", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.26", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.19", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.31", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", @@ -73,9 +73,9 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.16", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.16.tgz", - "integrity": "sha512-6X9PccsvbE8v6rVB1QVdjYaYIAHbBXived1K0SD+YeHwd/cCjfsetEZGqWF1q3WO4jiID72ViVb5FYOvj5N5uQ==", + "version": "0.0.1-alpha.19", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.19.tgz", + "integrity": "sha512-/UsnVQgsIVVCCdrWN7m/YHIYSzg5j+RLraytqte1l+smKi01Y9878/iX4cYWB68Ur1R9nt9C8HxVOtSvHfGMHQ==", "peerDependencies": { "tslib": "^2.6.2" } @@ -4035,9 +4035,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -7366,13 +7366,6 @@ "dev": true, "license": "MIT" }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true, - "license": "MIT" - }, "node_modules/node-emoji": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", @@ -7437,9 +7430,9 @@ } }, "node_modules/npm": { - "version": "10.9.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.0.tgz", - "integrity": "sha512-ZanDioFylI9helNhl2LNd+ErmVD+H5I53ry41ixlLyCBgkuYb+58CvbAp99hW+zr5L9W4X7CchSoeqKdngOLSw==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.1.tgz", + "integrity": "sha512-yJUw03xLqjiv1D52oHeoS5qmOEC5hkJlhP1cWlSrCgshuxWVyFEEK3M3hLC0NwbTaklLTYrhoIanYsuNP5WUKg==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -7526,21 +7519,21 @@ "@npmcli/fs": "^4.0.0", "@npmcli/map-workspaces": "^4.0.1", "@npmcli/package-json": "^6.0.1", - "@npmcli/promise-spawn": "^8.0.1", + "@npmcli/promise-spawn": "^8.0.2", "@npmcli/redact": "^3.0.0", "@npmcli/run-script": "^9.0.1", - "@sigstore/tuf": "^2.3.4", + "@sigstore/tuf": "^3.0.0", "abbrev": "^3.0.0", "archy": "~1.0.0", "cacache": "^19.0.1", "chalk": "^5.3.0", - "ci-info": "^4.0.0", + "ci-info": "^4.1.0", "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", "glob": "^10.4.5", "graceful-fs": "^4.2.11", - "hosted-git-info": "^8.0.0", + "hosted-git-info": "^8.0.2", "ini": "^5.0.0", "init-package-json": "^7.0.1", "is-cidr": "^5.1.0", @@ -7552,11 +7545,11 @@ "libnpmhook": "^11.0.0", "libnpmorg": "^7.0.0", "libnpmpack": "^8.0.0", - "libnpmpublish": "^10.0.0", + "libnpmpublish": "^10.0.1", "libnpmsearch": "^8.0.0", "libnpmteam": "^7.0.0", "libnpmversion": "^7.0.0", - "make-fetch-happen": "^14.0.1", + "make-fetch-happen": "^14.0.3", "minimatch": "^9.0.5", "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", @@ -7565,14 +7558,14 @@ "nopt": "^8.0.0", "normalize-package-data": "^7.0.0", "npm-audit-report": "^6.0.0", - "npm-install-checks": "^7.1.0", + "npm-install-checks": "^7.1.1", "npm-package-arg": "^12.0.0", "npm-pick-manifest": "^10.0.0", "npm-profile": "^11.0.1", - "npm-registry-fetch": "^18.0.1", + "npm-registry-fetch": "^18.0.2", "npm-user-validate": "^3.0.0", "p-map": "^4.0.0", - "pacote": "^19.0.0", + "pacote": "^19.0.1", "parse-conflict-json": "^4.0.0", "proc-log": "^5.0.0", "qrcode-terminal": "^0.12.0", @@ -7638,23 +7631,6 @@ "node": ">=4" } }, - "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, "node_modules/npm-run-all/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -7675,49 +7651,6 @@ "node": ">=4" } }, - "node_modules/npm-run-all/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/npm-run-all/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-all/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "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", @@ -7731,19 +7664,6 @@ "node": ">=4" } }, - "node_modules/npm-run-all/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/npm-run-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", @@ -7805,7 +7725,7 @@ } }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -8020,14 +7940,14 @@ } }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "8.0.0", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "cacache": "^19.0.0", "json-parse-even-better-errors": "^4.0.0", - "pacote": "^19.0.0", + "pacote": "^20.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5" }, @@ -8035,6 +7955,37 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { + "version": "20.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm/node_modules/@npmcli/name-from-folder": { "version": "3.0.0", "dev": true, @@ -8072,7 +8023,7 @@ } }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "8.0.1", + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -8131,27 +8082,6 @@ "node": ">=14" } }, - "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "2.3.2", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/core": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { "version": "0.3.2", "dev": true, @@ -8161,184 +8091,17 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/@sigstore/sign": { - "version": "2.3.2", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "make-fetch-happen": "^13.0.1", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/@npmcli/agent": { - "version": "2.2.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/@npmcli/fs": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/cacache": { - "version": "18.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/make-fetch-happen": { - "version": "13.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/minipass-fetch": { - "version": "3.0.5", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/proc-log": { - "version": "4.2.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/ssri": { - "version": "10.0.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/unique-filename": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/unique-slug": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "2.3.4", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { "@sigstore/protobuf-specs": "^0.3.2", - "tuf-js": "^2.2.1" + "tuf-js": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/verify": { - "version": "1.2.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.1.0", - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@tufjs/canonical-json": { @@ -8350,19 +8113,6 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/@tufjs/models": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/abbrev": { "version": "3.0.0", "dev": true, @@ -8593,7 +8343,7 @@ } }, "node_modules/npm/node_modules/ci-info": { - "version": "4.0.0", + "version": "4.1.0", "dev": true, "funding": [ { @@ -8675,7 +8425,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", "dev": true, "inBundle": true, "license": "MIT", @@ -8716,12 +8466,12 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.3.6", + "version": "4.3.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -8732,12 +8482,6 @@ } } }, - "node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/diff": { "version": "5.2.0", "dev": true, @@ -8854,7 +8598,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "8.0.0", + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -9192,7 +8936,7 @@ } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "10.0.0", + "version": "10.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -9203,7 +8947,7 @@ "npm-registry-fetch": "^18.0.1", "proc-log": "^5.0.0", "semver": "^7.3.7", - "sigstore": "^2.2.0", + "sigstore": "^3.0.0", "ssri": "^12.0.0" }, "engines": { @@ -9258,7 +9002,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "14.0.1", + "version": "14.0.3", "dev": true, "inBundle": true, "license": "ISC", @@ -9270,7 +9014,7 @@ "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", + "negotiator": "^1.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "ssri": "^12.0.0" @@ -9279,6 +9023,15 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/npm/node_modules/minimatch": { "version": "9.0.5", "dev": true, @@ -9470,7 +9223,7 @@ } }, "node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", + "version": "0.6.4", "dev": true, "inBundle": true, "license": "MIT", @@ -9746,7 +9499,7 @@ } }, "node_modules/npm/node_modules/npm-install-checks": { - "version": "7.1.0", + "version": "7.1.1", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -9822,7 +9575,7 @@ } }, "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "18.0.1", + "version": "18.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -9878,13 +9631,13 @@ } }, "node_modules/npm/node_modules/package-json-from-dist": { - "version": "1.0.0", + "version": "1.0.1", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0" }, "node_modules/npm/node_modules/pacote": { - "version": "19.0.0", + "version": "19.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -9903,7 +9656,7 @@ "npm-registry-fetch": "^18.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", - "sigstore": "^2.2.0", + "sigstore": "^3.0.0", "ssri": "^12.0.0", "tar": "^6.1.11" }, @@ -9994,7 +9747,7 @@ } }, "node_modules/npm/node_modules/promise-call-limit": { - "version": "3.0.1", + "version": "3.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -10152,20 +9905,72 @@ } }, "node_modules/npm/node_modules/sigstore": { - "version": "2.3.1", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", "@sigstore/protobuf-specs": "^0.3.2", - "@sigstore/sign": "^2.3.2", - "@sigstore/tuf": "^2.3.4", - "@sigstore/verify": "^1.2.1" + "@sigstore/sign": "^3.0.0", + "@sigstore/tuf": "^3.0.0", + "@sigstore/verify": "^2.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/core": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^14.0.1", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/smart-buffer": { @@ -10243,7 +10048,7 @@ } }, "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.18", + "version": "3.0.20", "dev": true, "inBundle": true, "license": "CC0-1.0" @@ -10404,153 +10209,30 @@ } }, "node_modules/npm/node_modules/tuf-js": { - "version": "2.2.1", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@tufjs/models": "2.0.1", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js/node_modules/@npmcli/agent": { - "version": "2.2.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js/node_modules/@npmcli/fs": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js/node_modules/cacache": { - "version": "18.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js/node_modules/make-fetch-happen": { - "version": "13.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/tuf-js/node_modules/minipass-fetch": { - "version": "3.0.5", + "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { + "version": "3.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/npm/node_modules/tuf-js/node_modules/proc-log": { - "version": "4.2.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js/node_modules/ssri": { - "version": "10.0.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js/node_modules/unique-filename": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js/node_modules/unique-slug": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/unique-filename": { @@ -10693,7 +10375,7 @@ } }, "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "MIT", diff --git a/package.json b/package.json index e1919e3..6f0ecde 100644 --- a/package.json +++ b/package.json @@ -63,13 +63,17 @@ }, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.16", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.26", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.19", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.31", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", "js-sha512": "^0.9.0", "tweetnacl": "^1.0.3" + }, + "overrides": { + "cross-spawn": "7.0.6", + "npm": "10.9.1" } } From 8ed855ea5707acff56a6431e134da5de2ffdaeeb Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 12 Dec 2024 10:13:47 +0800 Subject: [PATCH 54/85] chore: upgrading npm packages to avoid vulnerabilities --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 358304a..31e78d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1014,9 +1014,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", - "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", + "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -7327,9 +7327,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "dev": true, "funding": [ { From 8d8c3faad9103b197c5eb0483d3b96d3c7940f34 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Wed, 6 Nov 2024 15:30:16 +0800 Subject: [PATCH 55/85] refactor: generic type info capture as PType has been changed in puya-ts From ed63f03fe4fc07fadab9e3abf0a88cf6f4815dc0 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 11 Nov 2024 09:27:28 +0800 Subject: [PATCH 56/85] feat: implement stubs for UintN, UFixedNxM, Byte, Bool, Str arc4 types --- src/constants.ts | 1 + src/impl/encoded-types.ts | 199 ++ src/runtime-helpers.ts | 1 + src/subcontexts/contract-context.ts | 6 +- src/test-transformer/node-factory.ts | 25 + src/test-transformer/visitors.ts | 43 +- src/typescript-helpers.ts | 4 + tests/arc4/bool.spec.ts | 49 + tests/arc4/byte.spec.ts | 161 + tests/arc4/str.spec.ts | 102 + tests/arc4/ufixednxm.spec.ts | 179 + tests/arc4/uintn.spec.ts | 267 ++ .../arc4-primitive-ops/contract.algo.ts | 347 ++ .../Arc4PrimitiveOpsContract.approval.teal | 2893 +++++++++++++++++ .../data/Arc4PrimitiveOpsContract.arc32.json | 1137 +++++++ .../data/Arc4PrimitiveOpsContract.clear.teal | 5 + 16 files changed, 5409 insertions(+), 10 deletions(-) create mode 100644 src/impl/encoded-types.ts create mode 100644 tests/arc4/bool.spec.ts create mode 100644 tests/arc4/byte.spec.ts create mode 100644 tests/arc4/str.spec.ts create mode 100644 tests/arc4/ufixednxm.spec.ts create mode 100644 tests/arc4/uintn.spec.ts create mode 100644 tests/artifacts/arc4-primitive-ops/contract.algo.ts create mode 100644 tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal create mode 100644 tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json create mode 100644 tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.clear.teal diff --git a/src/constants.ts b/src/constants.ts index dd5627d..2536444 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -6,6 +6,7 @@ export const MAX_UINT8 = 2 ** 8 - 1 export const MAX_UINT64 = 2n ** 64n - 1n export const MAX_UINT512 = 2n ** 512n - 1n export const MAX_BYTES_SIZE = 4096 +export const MAX_LOG_SIZE = 1024 export const MAX_ITEMS_IN_LOG = 32 export const MAX_BOX_SIZE = 32768 export const BITS_IN_BYTE = 8 diff --git a/src/impl/encoded-types.ts b/src/impl/encoded-types.ts new file mode 100644 index 0000000..119b4f1 --- /dev/null +++ b/src/impl/encoded-types.ts @@ -0,0 +1,199 @@ +import { Bytes, bytes, internal, StringCompat } from '@algorandfoundation/algorand-typescript' +import { + BitSize, + Bool, + Byte, + CompatForArc4Int, + NativeForArc4Int, + Str, + UFixedNxM, + UintN, +} from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import assert from 'assert' +import { ABI_RETURN_VALUE_LOG_PREFIX, BITS_IN_BYTE, UINT64_SIZE } from '../constants' +import { TypeInfo } from '../encoders' +import { DeliberateAny } from '../typescript-helpers' +import { asBigUint, asBigUintCls, asBytesCls, asUint64, asUint8Array } from '../util' + +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)) +export class UintNImpl extends UintN { + private value: Uint8Array + private bitSize: N + private typeInfo: TypeInfo + + constructor(typeInfoString: string, v?: CompatForArc4Int) { + super(v) + this.typeInfo = JSON.parse(typeInfoString) + this.bitSize = parseInt((this.typeInfo.genericArgs as TypeInfo[])![0].name, 10) as N + + assert([8, 16, 32, 64, 128, 256, 512].includes(this.bitSize), `Invalid bit size ${this.bitSize}`) + + const bigIntValue = asBigUintCls(v ?? 0n).valueOf() + const maxValue = maxBigIntValue(this.bitSize) + assert(bigIntValue <= maxValue, `expected value <= ${maxValue}, got: ${bigIntValue}`) + + this.value = encodingUtil.bigIntToUint8Array(bigIntValue, maxBytesLength(this.bitSize)) + } + + get native(): NativeForArc4Int { + const bigIntValue = encodingUtil.uint8ArrayToBigInt(this.value) + return (this.bitSize <= UINT64_SIZE ? asUint64(bigIntValue) : asBigUint(bigIntValue)) as NativeForArc4Int + } + + get bytes(): bytes { + return Bytes(this.value) + } + + static fromBytesImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): UintNImpl { + const result = new UintNImpl(typeInfo) + result.value = asUint8Array(value) + return result + } + + static fromLogImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): UintNImpl { + const bytesValue = asBytesCls(value) + assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') + return UintNImpl.fromBytesImpl(typeInfo, bytesValue.slice(4)) + } +} + +const regExpNxM = (maxPrecision: number) => new RegExp(`^\\d*\\.?\\d{0,${maxPrecision}}$`) +const trimTrailingDecimalZeros = (v: string) => v.replace(/(\d+\.\d*?)0+$/, '$1').replace(/\.$/, '') +export class UFixedNxMImpl extends UFixedNxM { + private value: Uint8Array + private typeInfo: TypeInfo + private bitSize: N + private precision: M + + constructor(typeInfoString: string, v: `${number}.${number}`) { + super(v) + this.typeInfo = JSON.parse(typeInfoString) + this.bitSize = parseInt((this.typeInfo.genericArgs as TypeInfo[])![0].name, 10) as N + this.precision = parseInt((this.typeInfo.genericArgs as TypeInfo[])![1].name, 10) as M + + const trimmedValue = trimTrailingDecimalZeros(v) + assert(regExpNxM(this.precision).test(trimmedValue), `expected positive decimal literal with max of ${this.precision} decimal places`) + + const bigIntValue = BigInt(trimmedValue.replace('.', '')) + const maxValue = maxBigIntValue(this.bitSize) + assert(bigIntValue <= maxValue, `expected value <= ${maxValue}, got: ${bigIntValue}`) + + this.value = encodingUtil.bigIntToUint8Array(bigIntValue, maxBytesLength(this.bitSize)) + } + + get native(): NativeForArc4Int { + const bigIntValue = encodingUtil.uint8ArrayToBigInt(this.value) + return (this.bitSize <= UINT64_SIZE ? asUint64(bigIntValue) : asBigUint(bigIntValue)) as NativeForArc4Int + } + + get bytes(): bytes { + return Bytes(this.value) + } + + equals(other: UFixedNxM): boolean { + const otherImpl = other as UFixedNxMImpl + return this.bitSize === otherImpl.bitSize && this.precision === otherImpl.precision && this.value === otherImpl.value + } + + static fromBytesImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): UFixedNxM { + const result = new UFixedNxMImpl(typeInfo, '0.0') + result.value = asUint8Array(value) + return result + } + + static fromLogImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): UFixedNxM { + const bytesValue = asBytesCls(value) + assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') + return UFixedNxMImpl.fromBytesImpl(typeInfo, bytesValue.slice(4)) + } +} + +export class ByteImpl extends Byte { + private value: UintNImpl<8> + + constructor(typeInfoString: string, v: CompatForArc4Int<8>) { + super(v) + this.value = new UintNImpl<8>(typeInfoString, v) + } + + get native(): NativeForArc4Int<8> { + return this.value.native + } + + get bytes(): bytes { + return this.value.bytes + } + + static fromBytesImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): Byte { + return UintNImpl.fromBytesImpl(typeInfo, value) as Byte + } + + static fromLogImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): Byte { + return UintNImpl.fromLogImpl(typeInfo, value) as Byte + } +} + +export class StrImpl extends Str { + private value: Uint8Array + + constructor(s?: StringCompat) { + super() + const bytesValue = asBytesCls(s ?? '') + const bytesLength = encodeLength(bytesValue.length.asNumber()) + this.value = asUint8Array(bytesLength.concat(bytesValue)) + } + get native(): string { + return encodingUtil.uint8ArrayToUtf8(this.value.slice(ABI_LENGTH_SIZE)) + } + + get bytes(): bytes { + return Bytes(this.value) + } + + static fromBytesImpl(bytes: internal.primitives.StubBytesCompat): StrImpl { + const strValue = new StrImpl() + strValue.value = asUint8Array(bytes) + return strValue + } + + static fromLogImpl(value: internal.primitives.StubBytesCompat): StrImpl { + const bytesValue = asBytesCls(value) + assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') + return StrImpl.fromBytesImpl(bytesValue.slice(4)) + } +} +const TRUE_BIGINT_VALUE = 128n +const FALSE_BIGINT_VALUE = 0n + +export class BoolImpl extends Bool { + private value: Uint8Array + + constructor(v?: boolean) { + super(v) + this.value = encodingUtil.bigIntToUint8Array(v ? TRUE_BIGINT_VALUE : FALSE_BIGINT_VALUE, 1) + } + + get native(): boolean { + return encodingUtil.uint8ArrayToBigInt(this.value) === TRUE_BIGINT_VALUE + } + + get bytes(): bytes { + return Bytes(this.value) + } + + static fromBytesImpl(value: internal.primitives.StubBytesCompat): BoolImpl { + const result = new BoolImpl() + result.value = asUint8Array(value) + return result + } + + static fromLogImpl(value: internal.primitives.StubBytesCompat): BoolImpl { + const bytesValue = asBytesCls(value) + assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') + return BoolImpl.fromBytesImpl(bytesValue.slice(4)) + } +} diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 271d844..78f8803 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -5,6 +5,7 @@ import { DeliberateAny } from './typescript-helpers' import { nameOfType } from './util' export { attachAbiMetadata } from './abi-metadata' +export * from './impl/encoded-types' export function switchableValue(x: unknown): bigint | string | boolean { if (typeof x === 'boolean') return x diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 9d4e720..27c71ad 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -17,13 +17,9 @@ import { Transaction, } from '../impl/transactions' import { getGenericTypeInfo } from '../runtime-helpers' -import { DeliberateAny } from '../typescript-helpers' +import { DeliberateAny, IConstructor } from '../typescript-helpers' import { asUint64Cls } from '../util' -interface IConstructor { - new (...args: DeliberateAny[]): T -} - type StateTotals = Pick interface States { diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 7f336ee..0ce7252 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -1,5 +1,6 @@ import { FunctionPType } from '@algorandfoundation/puya-ts' import ts from 'typescript' +import { TypeInfo } from '../encoders' import type { DeliberateAny } from '../typescript-helpers' import { getPropertyNameAsString } from './helpers' @@ -77,4 +78,28 @@ export const nodeFactory = { [x, factory.createStringLiteral(info)], ) }, + + instantiateARC4EncodedType(node: ts.NewExpression, typeInfo?: TypeInfo) { + const infoString = JSON.stringify(typeInfo) + return factory.createNewExpression( + factory.createIdentifier(`runtimeHelpers.${node.expression.getText().replace('arc4.', '')}Impl`), + node.typeArguments, + [infoString ? factory.createStringLiteral(infoString) : undefined, ...(node.arguments ?? [])].filter((arg) => !!arg), + ) + }, + + callARC4EncodedStaticMethod(node: ts.CallExpression, typeInfo?: TypeInfo) { + const propertyAccessExpression = node.expression as ts.PropertyAccessExpression + const infoString = JSON.stringify(typeInfo) + const updatedPropertyAccessExpression = factory.createPropertyAccessExpression( + factory.createIdentifier(`runtimeHelpers.${propertyAccessExpression.expression.getText().replace('arc4.', '')}Impl`), + `${propertyAccessExpression.name.getText()}Impl`, + ) + + return factory.createCallExpression( + updatedPropertyAccessExpression, + node.typeArguments, + [infoString ? factory.createStringLiteral(infoString) : undefined, ...(node.arguments ?? [])].filter((arg) => !!arg), + ) + }, } satisfies Record ts.Node> diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index fa8fee2..2d5b07d 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -1,5 +1,7 @@ import { anyPType, + ARC4BooleanType, + ARC4StringType, ARC4StructType, ARC4TupleType, BoxMapPType, @@ -106,9 +108,21 @@ class ExpressionVisitor { // `voted = LocalState()` is resolved to FunctionPType with returnType LocalState if (type instanceof FunctionPType) type = type.returnType - if (isGenericType(type)) { - const info = getGenericTypeInfo(type) - return nodeFactory.captureGenericTypeInfo(ts.visitEachChild(node, this.visit, this.context), JSON.stringify(info)) + const isGeneric = isGenericType(type) + const isArc4Encoded = isArc4EncodedType(type) + if (isGeneric || isArc4Encoded) { + let updatedNode = node + const info = isGeneric ? getGenericTypeInfo(type) : undefined + if (isArc4EncodedType(type)) { + if (ts.isNewExpression(updatedNode)) { + updatedNode = nodeFactory.instantiateARC4EncodedType(updatedNode, info) + } else if (ts.isCallExpression(updatedNode) && isCallingARC4EncodedStaticMethod(updatedNode)) { + updatedNode = nodeFactory.callARC4EncodedStaticMethod(updatedNode, info) + } + } + return isGeneric + ? nodeFactory.captureGenericTypeInfo(ts.visitEachChild(updatedNode, this.visit, this.context), JSON.stringify(info)) + : ts.visitEachChild(updatedNode, this.visit, this.context) } } return ts.visitEachChild(node, this.visit, this.context) @@ -172,6 +186,7 @@ class FunctionOrMethodVisitor { return nodeFactory.prefixUnaryOp(node.operand, tokenText) } } + /* * capture generic type info in test functions; e.g. * ``` @@ -182,7 +197,7 @@ class FunctionOrMethodVisitor { * }) * ``` */ - if (this.isFunction && ts.isVariableDeclaration(node) && node.initializer) { + if (ts.isVariableDeclaration(node) && node.initializer) { return new VariableInitializerVisitor(this.context, this.helper, node).result() } @@ -191,12 +206,17 @@ class FunctionOrMethodVisitor { * ``` * it('should work', () => { * expect(() => new UintN<32>(2 ** 32)).toThrowError(`expected value <= ${2 ** 32 - 1}`) + * expect(UintN.fromBytes>('').bytes).toEqual(Bytes()) * }) * ``` */ - if (this.isFunction && ts.isNewExpression(node)) { + if (ts.isNewExpression(node)) { + return new ExpressionVisitor(this.context, this.helper, node).result() + } + if (ts.isCallExpression(node) && isCallingARC4EncodedStaticMethod(node)) { return new ExpressionVisitor(this.context, this.helper, node).result() } + return node } } @@ -277,6 +297,11 @@ const isGenericType = (type: PType): boolean => UintNType, ) +const isArc4EncodedType = (type: PType): boolean => + instanceOfAny(type, ARC4StructType, ARC4TupleType, DynamicArrayType, StaticArrayType, UFixedNxMType, UintNType) || + type === ARC4StringType || + type === ARC4BooleanType + const getGenericTypeInfo = (type: PType): TypeInfo => { const genericArgs: TypeInfo[] | Record = [] @@ -310,3 +335,11 @@ const getGenericTypeInfo = (type: PType): TypeInfo => { } return result } + +const isCallingARC4EncodedStaticMethod = (node: ts.CallExpression) => { + if (node.expression.kind !== ts.SyntaxKind.PropertyAccessExpression) return false + const propertyAccessExpression = node.expression as ts.PropertyAccessExpression + const staticMethodNames = ['fromBytes', 'fromLog'] + const propertyName = propertyAccessExpression.name.kind === ts.SyntaxKind.Identifier ? propertyAccessExpression.name.text : '' + return staticMethodNames.includes(propertyName) +} diff --git a/src/typescript-helpers.ts b/src/typescript-helpers.ts index a7bd1b5..d933a6c 100644 --- a/src/typescript-helpers.ts +++ b/src/typescript-helpers.ts @@ -25,3 +25,7 @@ export function instanceOfAny { return types.some((t) => x instanceof t) } + +export interface IConstructor { + new (...args: DeliberateAny[]): T +} diff --git a/tests/arc4/bool.spec.ts b/tests/arc4/bool.spec.ts new file mode 100644 index 0000000..143c5c9 --- /dev/null +++ b/tests/arc4/bool.spec.ts @@ -0,0 +1,49 @@ +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { Bool } from '@algorandfoundation/algorand-typescript/arc4' +import { afterEach, describe, expect, test } from 'vitest' +import { ABI_RETURN_VALUE_LOG_PREFIX } from '../../src/constants' +import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' +import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' +import { asUint8Array } from '../util' + +describe('arc4.Bool', async () => { + const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const ctx = new TestExecutionContext() + + afterEach(async () => { + ctx.reset() + }) + + 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) + }) + + 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 = Bool.fromBytes(Bytes(value)) + expect(result.native).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 = Bool.fromLog(Bytes(paddedValue)) + expect(result.native).toEqual(avmResult) + }) + + test.each([ + [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(() => Bool.fromLog(Bytes(paddedValue))).toThrowError('ABI return prefix not found') + }) +}) diff --git a/tests/arc4/byte.spec.ts b/tests/arc4/byte.spec.ts new file mode 100644 index 0000000..c39aae6 --- /dev/null +++ b/tests/arc4/byte.spec.ts @@ -0,0 +1,161 @@ +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { Byte } from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { afterEach, describe, expect, it, test } from 'vitest' +import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_UINT64 } from '../../src/constants' +import { asBigUintCls } from '../../src/util' +import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' +import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' +import { asUint8Array } from '../util' + +const invalidBytesLengthError = 'byte string must be 1 byte long' +describe('arc4.Byte', async () => { + const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const ctx = new TestExecutionContext() + + afterEach(async () => { + 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() + + await expect(getAvmResult({ appClient }, 'verify_byte_init', asUint8Array(bytesValue))).rejects.toThrowError() + expect(() => new Byte(value)).toThrowError(`expected value <= ${2 ** 8 - 1}`) + }) + + test.each([ + [0, 0], + [255, 255], + [2 ** 8 - 1, 2 ** 8 - 1], + ])('instantiating Byte should work for %s', async (value, expected) => { + const bytesValue = asBigUintCls(value).toBytes() + const avmResult = await getAvmResult({ appClient }, 'verify_byte_init', asUint8Array(bytesValue)) + + const result = new Byte(value) + + expect(result.native).toEqual(expected) + expect(avmResult).toEqual(expected) + }) + + test.each([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)) + }) + + describe.each(['eq', 'ne', 'lt', 'le', 'gt', 'ge'])('logical operators', async (op) => { + const operator = (function () { + switch (op) { + case 'eq': + return '===' + case 'ne': + return '!==' + case 'lt': + return '<' + case 'le': + return '<=' + case 'gt': + return '>' + case 'ge': + return '>=' + default: + throw new Error(`Unknown operator: ${op}`) + } + })() + describe.each([ + [0, 0], + [0, 1], + [0, 255], + [255, 42], + [255, 255], + ])(`${operator}`, async (a, b) => { + const getStubResult = (a: Byte, b: Byte) => { + switch (operator) { + case '===': + return a.equals(b) + case '!==': + return !a.equals(b) + case '<': + return a.native < b.native + case '<=': + return a.native <= b.native + case '>': + return a.native > b.native + case '>=': + return a.native >= b.native + default: + throw new Error(`Unknown operator: ${op}`) + } + } + it(`${a} ${operator} ${b}`, async () => { + const bytesValueA = asBigUintCls(a).toBytes() + const bytesValueB = asBigUintCls(b).toBytes() + const avmResult = await getAvmResult({ appClient }, `verify_byte_byte_${op}`, asUint8Array(bytesValueA), asUint8Array(bytesValueB)) + + const encodedA = new Byte(a) + const encodedB = new Byte(b) + const result = getStubResult(encodedA, encodedB) + + expect(result).toEqual(avmResult) + }) + }) + }) + + test.each([ + encodingUtil.bigIntToUint8Array(0n, 1), + encodingUtil.bigIntToUint8Array(42n, 1), + encodingUtil.bigIntToUint8Array(2n ** 8n - 1n, 1), + ])('create Byte from bytes', async (value) => { + const avmResult = await getAvmResult({ appClient }, 'verify_byte_from_bytes', value) + const result = Byte.fromBytes(Bytes(value)) + + expect(result.native).toEqual(avmResult) + }) + + test.each([encodingUtil.bigIntToUint8Array(0n, 2), encodingUtil.bigIntToUint8Array(255n, 8)])( + 'sdk throws error when creating Byte from bytes with invalid length', + async (value) => { + await expect(getAvmResult({ appClient }, 'verify_byte_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError) + + const result = Byte.fromBytes(Bytes(value)) + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }, + ) + + test.each([ + [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))) + const avmResult = await getAvmResult({ appClient }, 'verify_byte_from_log', logValue) + + const result = Byte.fromLog(Bytes(logValue)) + expect(avmResult).toEqual(expected) + expect(result.native).toEqual(expected) + }) + + test.each([ + [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(() => Byte.fromLog(Bytes(logValue))).toThrowError('ABI return prefix not found') + }) + + test.each([ + 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) + + const result = Byte.fromLog(Bytes(logValue)) + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }) +}) diff --git a/tests/arc4/str.spec.ts b/tests/arc4/str.spec.ts new file mode 100644 index 0000000..325af58 --- /dev/null +++ b/tests/arc4/str.spec.ts @@ -0,0 +1,102 @@ +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { Str } from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { afterEach, describe, expect, test } from 'vitest' +import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_LOG_SIZE } from '../../src/constants' +import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' +import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' +import { asUint8Array } from '../util' + +describe('arc4.Str', async () => { + const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const ctx = new TestExecutionContext() + + afterEach(async () => { + ctx.reset() + }) + + test.each([ + '', + 'hello', + '0'.repeat(MAX_LOG_SIZE - 13), // Max log size is 1024 + ])('instantiate Str with %s', async (value) => { + const avmResult = await getAvmResult({ appClient }, 'verify_string_init', asUint8Array(value)) + const result = new Str(`Hello, ${value}`) + expect(result.native).toEqual(avmResult) + }) + + test.each([ + ['hello', 'world', 'helloworld'], + ['foo', 'bar', 'foobar'], + ])('add Str values', async (a, b, expected) => { + const avmResult = await getAvmResult({ appClient }, 'verify_string_add', asUint8Array(a), asUint8Array(b)) + const aStr = new Str(a) + const bStr = new Str(b) + const result = new Str(aStr.native.concat(bStr.native)) + expect(avmResult).toEqual(expected) + expect(result.native).toEqual(expected) + }) + + test.each([ + ['', ''], + ['hello', 'hello'], + ['foo', 'Foo'], + ['foo', 'bar'], + ])('%s equals %s', async (a, b) => { + const avmResult = await getAvmResult({ appClient }, 'verify_string_eq', asUint8Array(a), asUint8Array(b)) + const aStr = new Str(a) + const bStr = new Str(b) + const result = aStr.equals(bStr) + expect(result).toEqual(avmResult) + }) + + test.each([ + '', + 'hello', + '0'.repeat(MAX_LOG_SIZE - 8), // Max log size is 1024 + ])('should be able to get bytes representation of %s', async (value) => { + const avmResult = await getAvmResult({ appClient }, 'verify_string_bytes', asUint8Array(value)) + const result = new Str(value) + expect(result.bytes).toEqual(avmResult) + }) + + test.each([ + asUint8Array(''), + asUint8Array('hello'), + asUint8Array('0'.repeat(MAX_LOG_SIZE - 13)), // Max log size is 1024 + ])('create Str from bytes', async (value) => { + const paddedValue = new Uint8Array([...encodingUtil.bigIntToUint8Array(BigInt(value.length), 2), ...value]) + const avmResult = await getAvmResult({ appClient }, 'verify_string_from_bytes', paddedValue) + const result = Str.fromBytes(Bytes(paddedValue)) + expect(result.native).toEqual(avmResult) + }) + + test.each([ + asUint8Array(''), + asUint8Array('hello'), + asUint8Array('0'.repeat(MAX_LOG_SIZE - 13)), // Max log size is 1024 + ])('create Str from log', async (value) => { + const paddedValue = new Uint8Array([ + ...asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX), + ...encodingUtil.bigIntToUint8Array(BigInt(value.length), 2), + ...value, + ]) + const avmResult = await getAvmResult({ appClient }, 'verify_string_from_log', paddedValue) + const result = Str.fromLog(Bytes(paddedValue)) + expect(result.native).toEqual(avmResult) + }) + + test.each([ + [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) => { + 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)'), + ) + expect(() => Str.fromLog(Bytes(paddedValue))).toThrowError('ABI return prefix not found') + }) +}) diff --git a/tests/arc4/ufixednxm.spec.ts b/tests/arc4/ufixednxm.spec.ts new file mode 100644 index 0000000..6c0d3f5 --- /dev/null +++ b/tests/arc4/ufixednxm.spec.ts @@ -0,0 +1,179 @@ +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { UFixedNxM } from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { afterEach, describe, expect, test } 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' + +const invalidBytesLengthError = (length: number) => `byte string must correspond to a ufixed${length}` +describe('arc4.UFixedNxM', async () => { + const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const ctx = new TestExecutionContext() + + afterEach(async () => { + ctx.reset() + }) + + test.each(['-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( + 'expected positive decimal literal with max of 8 decimal places', + ) + }, + ) + + test.each(['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'])( + 'should be able to get UFixedNxM<32,8> bytes representation of %s', + async (value) => { + 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) + expect(a.bytes).toEqual(avmResult) + }, + ) + + test.each(['0', '1', '25.5', '42.94967295', '11579208923731619542357098500868790785326998466564056403945758.4007913129639935'])( + 'should be able to get UFixedNxM<256,16> bytes representation of %s', + async (value) => { + 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) + expect(a.bytes).toEqual(avmResult) + }, + ) + + test.each([ + 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) => { + const avmResult = await getAvmResult({ appClient }, 'verify_ufixednxm_from_bytes', value) + const result = UFixedNxM.fromBytes>(Bytes(value)) + + expect(result.native).toEqual(avmResult) + }) + + test.each([ + 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)) + + const result = UFixedNxM.fromBytes>(Bytes(value)) + expect(result.bytes).toEqual(value) + }) + + test.each([ + [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))) + const avmResult = await getAvmResult({ appClient }, 'verify_ufixednxm_from_log', logValue) + + const result = UFixedNxM.fromLog>(Bytes(logValue)) + expect(avmResult).toEqual(expected) + expect(result.native).toEqual(expected) + }) + + test.each([ + [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(() => UFixedNxM.fromLog>(Bytes(logValue))).toThrowError('ABI return prefix not found') + }) + + test.each([ + 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)) + + const result = UFixedNxM.fromLog>(Bytes(logValue)) + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }) + + test.each([ + 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) => { + const avmResult = await getAvmResult({ appClient }, 'verify_bigufixednxm_from_bytes', value) + const result = UFixedNxM.fromBytes>(Bytes(value)) + + expect(result.native).toEqual(avmResult) + }) + + test.each([ + 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)) + + const result = UFixedNxM.fromBytes>(Bytes(value)) + expect(result.bytes).toEqual(value) + }) + + test.each([ + [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))) + const avmResult = await getAvmResult({ appClient }, 'verify_bigufixednxm_from_log', logValue) + + const result = UFixedNxM.fromLog>(Bytes(logValue)) + expect(avmResult).toEqual(expected) + expect(result.native).toEqual(expected) + }) + + test.each([ + [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(() => UFixedNxM.fromLog>(Bytes(logValue))).toThrowError('ABI return prefix not found') + }) + + test.each([ + 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), + ) + + const result = UFixedNxM.fromLog>(Bytes(logValue)) + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }) +}) diff --git a/tests/arc4/uintn.spec.ts b/tests/arc4/uintn.spec.ts new file mode 100644 index 0000000..dd9a48c --- /dev/null +++ b/tests/arc4/uintn.spec.ts @@ -0,0 +1,267 @@ +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { UintN } from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { afterEach, describe, expect, it, test } from 'vitest' +import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_UINT512, MAX_UINT64 } from '../../src/constants' +import { DeliberateAny } from '../../src/typescript-helpers' +import { asBigUintCls } from '../../src/util' +import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' +import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' +import { asUint8Array } from '../util' + +const invalidBytesLengthError = (length: number) => `byte string must correspond to a uint${length}` +describe('arc4.UintN', async () => { + const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const ctx = new TestExecutionContext() + + afterEach(async () => { + 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() + + await expect(getAvmResult({ appClient }, 'verify_uintn_init', asUint8Array(bytesValue))).rejects.toThrowError() + expect(() => new UintN<32>(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() + + await expect(getAvmResult({ appClient }, 'verify_biguintn_init', asUint8Array(bytesValue))).rejects.toThrowError() + expect(() => new UintN<256>(value)).toThrowError(`expected value <= ${2 ** 256 - 1}`) + }) + + test.each([ + [0, 0], + [255, 255], + [2 ** 32 - 1, 2 ** 32 - 1], + ])('instantiating UintN<32> should work for %s', async (value, expected) => { + const bytesValue = asBigUintCls(value).toBytes() + const avmResult = await getAvmResult({ appClient }, 'verify_uintn_init', asUint8Array(bytesValue)) + + const result = new UintN<32>(value) + + expect(result.native).toEqual(BigInt(expected)) + expect(avmResult).toEqual(BigInt(expected)) + }) + + test.each([ + [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) => { + const bytesValue = asBigUintCls(value).toBytes() + const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_init', asUint8Array(bytesValue)) + + const result = new UintN<256>(value) + + expect(result.native).toEqual(BigInt(expected)) + expect(avmResult).toEqual(BigInt(expected)) + }) + + test.each([0, 1, 255])('should be able to get bytes representation of %s', async (value) => { + expect(new UintN<8>(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 1)) + expect(new UintN<16>(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 2)) + expect(new UintN<64>(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 8)) + expect(new UintN<512>(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 64)) + }) + + describe.each(['eq', 'ne', 'lt', 'le', 'gt', 'ge'])('logical operators', async (op) => { + const operator = (function () { + switch (op) { + case 'eq': + return '===' + case 'ne': + return '!==' + case 'lt': + return '<' + case 'le': + return '<=' + case 'gt': + return '>' + case 'ge': + return '>=' + default: + throw new Error(`Unknown operator: ${op}`) + } + })() + describe.each([ + [0, 0], + [0, 1], + [0, 255], + [255, 255], + [65535, 65535], + [255, 65535], + [MAX_UINT64, MAX_UINT64], + [65535, 4294967295], + [4294967295, MAX_UINT64], + [MAX_UINT64, MAX_UINT512], + [0, MAX_UINT512], + [1, MAX_UINT512], + [MAX_UINT512, MAX_UINT512], + ])(`${operator}`, async (a, b) => { + const getStubResult = (a: UintN, b: UintN) => { + switch (operator) { + case '===': + return a.equals(b) + case '!==': + return !a.equals(b) + case '<': + return a.native < b.native + case '<=': + return a.native <= b.native + case '>': + return a.native > b.native + case '>=': + return a.native >= b.native + default: + throw new Error(`Unknown operator: ${op}`) + } + } + it(`${a} ${operator} ${b}`, async () => { + const aType = a <= MAX_UINT64 ? 'uintn' : 'biguintn' + const bType = b <= MAX_UINT64 ? 'uintn' : 'biguintn' + const bytesValueA = asBigUintCls(a).toBytes() + const bytesValueB = asBigUintCls(b).toBytes() + const avmResult = await getAvmResult( + { appClient }, + `verify_${aType}_${bType}_${op}`, + asUint8Array(bytesValueA), + asUint8Array(bytesValueB), + ) + + 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) + const result = getStubResult(encodedA, encodedB) + + expect(result).toEqual(avmResult) + }) + }) + }) + + test.each([ + 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) => { + const avmResult = await getAvmResult({ appClient }, 'verify_uintn_from_bytes', value) + const result = UintN.fromBytes>(Bytes(value)) + + expect(result.native).toEqual(avmResult) + }) + + test.each([ + 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)) + + const result = UintN.fromBytes>(Bytes(value)) + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }) + + test.each([ + 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) => { + const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_from_bytes', value) + const result = UintN.fromBytes>(Bytes(value)) + + expect(result.native).toEqual(avmResult) + }) + + test.each([ + 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)) + + const result = UintN.fromBytes>(Bytes(value)) + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }) + + test.each([ + [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))) + const avmResult = await getAvmResult({ appClient }, 'verify_uintn_from_log', logValue) + + const result = UintN.fromLog>(Bytes(logValue)) + expect(avmResult).toEqual(expected) + expect(result.native).toEqual(expected) + }) + + test.each([ + [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(() => UintN.fromLog>(Bytes(logValue))).toThrowError('ABI return prefix not found') + }) + + test.each([ + 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 = UintN.fromLog>(Bytes(logValue)) + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }) + + test.each([ + [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))) + const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_from_log', logValue) + + const result = UintN.fromLog>(Bytes(logValue)) + expect(avmResult).toEqual(expected) + expect(result.native).toEqual(expected) + }) + + test.each([ + [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(() => UintN.fromLog>(Bytes(logValue))).toThrowError('ABI return prefix not found') + }) + + test.each([ + 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 = UintN.fromLog>(Bytes(logValue)) + expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) + }) +}) diff --git a/tests/artifacts/arc4-primitive-ops/contract.algo.ts b/tests/artifacts/arc4-primitive-ops/contract.algo.ts new file mode 100644 index 0000000..5c8a5ba --- /dev/null +++ b/tests/artifacts/arc4-primitive-ops/contract.algo.ts @@ -0,0 +1,347 @@ +import { arc4, BigUint, bytes } from '@algorandfoundation/algorand-typescript' +import { Bool, Byte, Contract, Str, UFixedNxM, UintN } from '@algorandfoundation/algorand-typescript/arc4' + +export class Arc4PrimitiveOpsContract extends Contract { + @arc4.abimethod() + public verify_uintn_uintn_eq(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return aUintN.equals(bUintN) + } + @arc4.abimethod() + public verify_biguintn_uintn_eq(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return aUintN.bytes.equals(bUintN.bytes) + } + @arc4.abimethod() + public verify_uintn_biguintn_eq(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return aUintN.bytes.equals(bUintN.bytes) + } + @arc4.abimethod() + public verify_biguintn_biguintn_eq(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return aUintN.equals(bUintN) + } + @arc4.abimethod() + public verify_byte_byte_eq(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aByte = new Byte(aBiguint) + const bByte = new Byte(bBiguint) + return aByte.equals(bByte) + } + @arc4.abimethod() + public verify_uintn_uintn_ne(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return !aUintN.equals(bUintN) + } + @arc4.abimethod() + public verify_biguintn_uintn_ne(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return !aUintN.bytes.equals(bUintN.bytes) + } + @arc4.abimethod() + public verify_uintn_biguintn_ne(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return !aUintN.bytes.equals(bUintN.bytes) + } + @arc4.abimethod() + public verify_biguintn_biguintn_ne(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return !aUintN.equals(bUintN) + } + @arc4.abimethod() + public verify_byte_byte_ne(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aByte = new Byte(aBiguint) + const bByte = new Byte(bBiguint) + return !aByte.equals(bByte) + } + @arc4.abimethod() + public verify_uintn_uintn_lt(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return aUintN.native < bUintN.native + } + @arc4.abimethod() + public verify_biguintn_uintn_lt(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return aUintN.native < BigUint(bUintN.native) + } + @arc4.abimethod() + public verify_uintn_biguintn_lt(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return BigUint(aUintN.native) < bUintN.native + } + @arc4.abimethod() + public verify_biguintn_biguintn_lt(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return aUintN.native < bUintN.native + } + @arc4.abimethod() + public verify_byte_byte_lt(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aByte = new Byte(aBiguint) + const bByte = new Byte(bBiguint) + return aByte.native < bByte.native + } + @arc4.abimethod() + public verify_uintn_uintn_le(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return aUintN.native <= bUintN.native + } + @arc4.abimethod() + public verify_biguintn_uintn_le(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return aUintN.native <= BigUint(bUintN.native) + } + @arc4.abimethod() + public verify_uintn_biguintn_le(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return BigUint(aUintN.native) <= bUintN.native + } + @arc4.abimethod() + public verify_biguintn_biguintn_le(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return aUintN.native <= bUintN.native + } + @arc4.abimethod() + public verify_byte_byte_le(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aByte = new Byte(aBiguint) + const bByte = new Byte(bBiguint) + return aByte.native <= bByte.native + } + @arc4.abimethod() + public verify_uintn_uintn_gt(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return aUintN.native > bUintN.native + } + @arc4.abimethod() + public verify_biguintn_uintn_gt(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return aUintN.native > BigUint(bUintN.native) + } + @arc4.abimethod() + public verify_uintn_biguintn_gt(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return BigUint(aUintN.native) > bUintN.native + } + @arc4.abimethod() + public verify_biguintn_biguintn_gt(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return aUintN.native > bUintN.native + } + @arc4.abimethod() + public verify_byte_byte_gt(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aByte = new Byte(aBiguint) + const bByte = new Byte(bBiguint) + return aByte.native > bByte.native + } + @arc4.abimethod() + public verify_uintn_uintn_ge(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return aUintN.native >= bUintN.native + } + @arc4.abimethod() + public verify_biguintn_uintn_ge(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<64>(bBiguint) + return aUintN.native >= BigUint(bUintN.native) + } + @arc4.abimethod() + public verify_uintn_biguintn_ge(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<64>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return BigUint(aUintN.native) >= bUintN.native + } + @arc4.abimethod() + public verify_biguintn_biguintn_ge(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aUintN = new UintN<512>(aBiguint) + const bUintN = new UintN<512>(bBiguint) + return aUintN.native >= bUintN.native + } + @arc4.abimethod() + public verify_byte_byte_ge(a: bytes, b: bytes): boolean { + const aBiguint = BigUint(a) + const bBiguint = BigUint(b) + const aByte = new Byte(aBiguint) + const bByte = new Byte(bBiguint) + return aByte.native >= bByte.native + } + @arc4.abimethod() + public verify_uintn_init(a: bytes): UintN<32> { + const aBiguint = BigUint(a) + return new UintN<32>(aBiguint) + } + @arc4.abimethod() + public verify_biguintn_init(a: bytes): UintN<256> { + const aBiguint = BigUint(a) + return new UintN<256>(aBiguint) + } + @arc4.abimethod() + public verify_byte_init(a: bytes): Byte { + const aBiguint = BigUint(a) + return new Byte(aBiguint) + } + @arc4.abimethod() + public verify_uintn_from_bytes(a: bytes): UintN<32> { + return UintN.fromBytes>(a) + } + @arc4.abimethod() + public verify_biguintn_from_bytes(a: bytes): UintN<256> { + return UintN.fromBytes>(a) + } + @arc4.abimethod() + public verify_byte_from_bytes(a: bytes): Byte { + return Byte.fromBytes(a) + } + @arc4.abimethod() + public verify_uintn_from_log(a: bytes): UintN<32> { + return UintN.fromLog>(a) + } + @arc4.abimethod() + public verify_biguintn_from_log(a: bytes): UintN<256> { + return UintN.fromLog>(a) + } + @arc4.abimethod() + public verify_byte_from_log(a: bytes): Byte { + return Byte.fromLog(a) + } + @arc4.abimethod() + public verify_ufixednxm_bytes(a: UFixedNxM<32, 8>): bytes { + return a.bytes + } + @arc4.abimethod() + public verify_bigufixednxm_bytes(a: UFixedNxM<256, 16>): bytes { + return a.bytes + } + @arc4.abimethod() + public verify_ufixednxm_from_bytes(a: bytes): UFixedNxM<32, 8> { + return UFixedNxM.fromBytes>(a) + } + @arc4.abimethod() + public verify_bigufixednxm_from_bytes(a: bytes): UFixedNxM<256, 16> { + return UFixedNxM.fromBytes>(a) + } + @arc4.abimethod() + public verify_ufixednxm_from_log(a: bytes): UFixedNxM<32, 8> { + return UFixedNxM.fromLog>(a) + } + @arc4.abimethod() + public verify_bigufixednxm_from_log(a: bytes): UFixedNxM<256, 16> { + return UFixedNxM.fromLog>(a) + } + @arc4.abimethod() + public verify_string_init(a: string): Str { + const result = new Str(`Hello, ${a}`) + return result + } + @arc4.abimethod() + public verify_string_add(a: Str, b: Str): Str { + const result = a.native.concat(b.native) + return new Str(result) + } + @arc4.abimethod() + public verify_string_eq(a: Str, b: Str): boolean { + return a.equals(b) + } + @arc4.abimethod() + public verify_string_bytes(a: string): bytes { + const result = new Str(a) + return result.bytes + } + @arc4.abimethod() + public verify_string_from_bytes(a: bytes): Str { + return Str.fromBytes(a) + } + @arc4.abimethod() + public verify_string_from_log(a: bytes): Str { + return Str.fromLog(a) + } + @arc4.abimethod() + public verify_bool_bytes(a: Bool): bytes { + return a.bytes + } + @arc4.abimethod() + public verify_bool_from_bytes(a: bytes): Bool { + return Bool.fromBytes(a) + } + @arc4.abimethod() + public verify_bool_from_log(a: bytes): Bool { + return Bool.fromLog(a) + } +} diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal new file mode 100644 index 0000000..c02361b --- /dev/null +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal @@ -0,0 +1,2893 @@ +#pragma version 10 + +tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.approvalProgram: + intcblock 1 8 64 0 + bytecblock 0x151f7c75 0x00 + callsub __puya_arc4_router__ + return + + +// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.__puya_arc4_router__() -> uint64: +__puya_arc4_router__: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 + // export class Arc4PrimitiveOpsContract extends Contract { + proto 0 1 + txn NumAppArgs + bz __puya_arc4_router___bare_routing@58 + 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 // 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" + txna ApplicationArgs 0 + match __puya_arc4_router___verify_uintn_uintn_eq_route@2 __puya_arc4_router___verify_biguintn_uintn_eq_route@3 __puya_arc4_router___verify_uintn_biguintn_eq_route@4 __puya_arc4_router___verify_biguintn_biguintn_eq_route@5 __puya_arc4_router___verify_byte_byte_eq_route@6 __puya_arc4_router___verify_uintn_uintn_ne_route@7 __puya_arc4_router___verify_biguintn_uintn_ne_route@8 __puya_arc4_router___verify_uintn_biguintn_ne_route@9 __puya_arc4_router___verify_biguintn_biguintn_ne_route@10 __puya_arc4_router___verify_byte_byte_ne_route@11 __puya_arc4_router___verify_uintn_uintn_lt_route@12 __puya_arc4_router___verify_biguintn_uintn_lt_route@13 __puya_arc4_router___verify_uintn_biguintn_lt_route@14 __puya_arc4_router___verify_biguintn_biguintn_lt_route@15 __puya_arc4_router___verify_byte_byte_lt_route@16 __puya_arc4_router___verify_uintn_uintn_le_route@17 __puya_arc4_router___verify_biguintn_uintn_le_route@18 __puya_arc4_router___verify_uintn_biguintn_le_route@19 __puya_arc4_router___verify_biguintn_biguintn_le_route@20 __puya_arc4_router___verify_byte_byte_le_route@21 __puya_arc4_router___verify_uintn_uintn_gt_route@22 __puya_arc4_router___verify_biguintn_uintn_gt_route@23 __puya_arc4_router___verify_uintn_biguintn_gt_route@24 __puya_arc4_router___verify_biguintn_biguintn_gt_route@25 __puya_arc4_router___verify_byte_byte_gt_route@26 __puya_arc4_router___verify_uintn_uintn_ge_route@27 __puya_arc4_router___verify_biguintn_uintn_ge_route@28 __puya_arc4_router___verify_uintn_biguintn_ge_route@29 __puya_arc4_router___verify_biguintn_biguintn_ge_route@30 __puya_arc4_router___verify_byte_byte_ge_route@31 __puya_arc4_router___verify_uintn_init_route@32 __puya_arc4_router___verify_biguintn_init_route@33 __puya_arc4_router___verify_byte_init_route@34 __puya_arc4_router___verify_uintn_from_bytes_route@35 __puya_arc4_router___verify_biguintn_from_bytes_route@36 __puya_arc4_router___verify_byte_from_bytes_route@37 __puya_arc4_router___verify_uintn_from_log_route@38 __puya_arc4_router___verify_biguintn_from_log_route@39 __puya_arc4_router___verify_byte_from_log_route@40 __puya_arc4_router___verify_ufixednxm_bytes_route@41 __puya_arc4_router___verify_bigufixednxm_bytes_route@42 __puya_arc4_router___verify_ufixednxm_from_bytes_route@43 __puya_arc4_router___verify_bigufixednxm_from_bytes_route@44 __puya_arc4_router___verify_ufixednxm_from_log_route@45 __puya_arc4_router___verify_bigufixednxm_from_log_route@46 __puya_arc4_router___verify_string_init_route@47 __puya_arc4_router___verify_string_add_route@48 __puya_arc4_router___verify_string_eq_route@49 __puya_arc4_router___verify_string_bytes_route@50 __puya_arc4_router___verify_string_from_bytes_route@51 __puya_arc4_router___verify_string_from_log_route@52 __puya_arc4_router___verify_bool_bytes_route@53 __puya_arc4_router___verify_bool_from_bytes_route@54 __puya_arc4_router___verify_bool_from_log_route@55 + intc_3 // 0 + retsub + +__puya_arc4_router___verify_uintn_uintn_eq_route@2: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:5 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_uintn_eq_route@3: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:13 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_biguintn_eq_route@4: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:21 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_biguintn_eq_route@5: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:29 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_byte_byte_eq_route@6: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:37 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_uintn_ne_route@7: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:45 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_uintn_ne_route@8: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:53 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_biguintn_ne_route@9: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:61 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_biguintn_ne_route@10: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:69 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_byte_byte_ne_route@11: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:77 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_uintn_lt_route@12: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:85 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_uintn_lt_route@13: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:93 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_biguintn_lt_route@14: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:101 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_biguintn_lt_route@15: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:109 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_byte_byte_lt_route@16: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:117 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_uintn_le_route@17: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:125 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_uintn_le_route@18: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:133 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_biguintn_le_route@19: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:141 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_biguintn_le_route@20: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:149 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_byte_byte_le_route@21: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:157 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_uintn_gt_route@22: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:165 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_uintn_gt_route@23: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:173 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_biguintn_gt_route@24: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:181 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_biguintn_gt_route@25: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:189 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_byte_byte_gt_route@26: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:197 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_uintn_ge_route@27: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:205 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_uintn_ge_route@28: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:213 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_biguintn_ge_route@29: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:221 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_biguintn_ge_route@30: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:229 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_byte_byte_ge_route@31: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:237 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_init_route@32: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:245 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_init_route@33: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:250 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_byte_init_route@34: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:255 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_uintn_from_bytes_route@35: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:260 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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() + callsub verify_uintn_from_bytes + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___verify_biguintn_from_bytes_route@36: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:264 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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() + callsub verify_biguintn_from_bytes + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___verify_byte_from_bytes_route@37: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:268 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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() + callsub verify_byte_from_bytes + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___verify_uintn_from_log_route@38: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:272 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_biguintn_from_log_route@39: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:276 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_byte_from_log_route@40: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:280 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_ufixednxm_bytes_route@41: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:284 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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() + callsub verify_ufixednxm_bytes + dup + len + itob + extract 6 2 + swap + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___verify_bigufixednxm_bytes_route@42: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:288 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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() + callsub verify_bigufixednxm_bytes + dup + len + itob + extract 6 2 + swap + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___verify_ufixednxm_from_bytes_route@43: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:292 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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() + callsub verify_ufixednxm_from_bytes + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___verify_bigufixednxm_from_bytes_route@44: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:296 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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() + callsub verify_bigufixednxm_from_bytes + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___verify_ufixednxm_from_log_route@45: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:300 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_bigufixednxm_from_log_route@46: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:304 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_string_init_route@47: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:308 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_string_add_route@48: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:313 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_string_eq_route@49: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:318 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_string_bytes_route@50: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:322 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_string_from_bytes_route@51: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:327 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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() + callsub verify_string_from_bytes + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___verify_string_from_log_route@52: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:331 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___verify_bool_bytes_route@53: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:335 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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() + callsub verify_bool_bytes + dup + len + itob + extract 6 2 + swap + concat + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___verify_bool_from_bytes_route@54: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:339 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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() + callsub verify_bool_from_bytes + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + retsub + +__puya_arc4_router___verify_bool_from_log_route@55: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:343 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is NoOp + txn ApplicationID + assert // is 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 + retsub + +__puya_arc4_router___bare_routing@58: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 + // export class Arc4PrimitiveOpsContract extends Contract { + txn OnCompletion + bnz __puya_arc4_router___after_if_else@62 + txn ApplicationID + ! + assert // is creating + intc_0 // 1 + retsub + +__puya_arc4_router___after_if_else@62: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 + // export class Arc4PrimitiveOpsContract extends Contract { + intc_3 // 0 + retsub + + +// 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.equals(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.equals(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.equals(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.equals(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.equals(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.equals(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_bytes(a: bytes) -> bytes: +verify_uintn_from_bytes: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:260-261 + // @arc4.abimethod() + // public verify_uintn_from_bytes(a: bytes): UintN<32> { + proto 1 1 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:262 + // return UintN.fromBytes>(a) + frame_dig -1 + retsub + + +// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_from_bytes(a: bytes) -> bytes: +verify_biguintn_from_bytes: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:264-265 + // @arc4.abimethod() + // public verify_biguintn_from_bytes(a: bytes): UintN<256> { + proto 1 1 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:266 + // return UintN.fromBytes>(a) + frame_dig -1 + retsub + + +// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_byte_from_bytes(a: bytes) -> bytes: +verify_byte_from_bytes: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:268-269 + // @arc4.abimethod() + // public verify_byte_from_bytes(a: bytes): Byte { + proto 1 1 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:270 + // return Byte.fromBytes(a) + frame_dig -1 + 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 UintN.fromLog>(a) + frame_dig -1 + extract 4 0 + frame_dig -1 + extract 0 4 + bytec_0 // 0x151f7c75 + == + assert // ARC4 prefix is valid + 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 UintN.fromLog>(a) + frame_dig -1 + extract 4 0 + frame_dig -1 + extract 0 4 + bytec_0 // 0x151f7c75 + == + assert // ARC4 prefix is valid + 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 Byte.fromLog(a) + frame_dig -1 + extract 4 0 + frame_dig -1 + extract 0 4 + bytec_0 // 0x151f7c75 + == + assert // ARC4 prefix is valid + retsub + + +// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_ufixednxm_bytes(a: bytes) -> bytes: +verify_ufixednxm_bytes: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:284-285 + // @arc4.abimethod() + // public verify_ufixednxm_bytes(a: UFixedNxM<32, 8>): bytes { + proto 1 1 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:286 + // return a.bytes + frame_dig -1 + retsub + + +// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_bigufixednxm_bytes(a: bytes) -> bytes: +verify_bigufixednxm_bytes: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:288-289 + // @arc4.abimethod() + // public verify_bigufixednxm_bytes(a: UFixedNxM<256, 16>): bytes { + proto 1 1 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:290 + // return a.bytes + frame_dig -1 + retsub + + +// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_ufixednxm_from_bytes(a: bytes) -> bytes: +verify_ufixednxm_from_bytes: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:292-293 + // @arc4.abimethod() + // public verify_ufixednxm_from_bytes(a: bytes): UFixedNxM<32, 8> { + proto 1 1 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:294 + // return UFixedNxM.fromBytes>(a) + frame_dig -1 + retsub + + +// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_bigufixednxm_from_bytes(a: bytes) -> bytes: +verify_bigufixednxm_from_bytes: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:296-297 + // @arc4.abimethod() + // public verify_bigufixednxm_from_bytes(a: bytes): UFixedNxM<256, 16> { + proto 1 1 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:298 + // return UFixedNxM.fromBytes>(a) + frame_dig -1 + 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 UFixedNxM.fromLog>(a) + frame_dig -1 + extract 4 0 + frame_dig -1 + extract 0 4 + bytec_0 // 0x151f7c75 + == + assert // ARC4 prefix is valid + 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 UFixedNxM.fromLog>(a) + frame_dig -1 + extract 4 0 + frame_dig -1 + extract 0 4 + bytec_0 // 0x151f7c75 + == + assert // ARC4 prefix is valid + 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.equals(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_bytes(a: bytes) -> bytes: +verify_string_from_bytes: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:327-328 + // @arc4.abimethod() + // public verify_string_from_bytes(a: bytes): Str { + proto 1 1 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:329 + // return Str.fromBytes(a) + frame_dig -1 + 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 Str.fromLog(a) + frame_dig -1 + extract 4 0 + frame_dig -1 + extract 0 4 + bytec_0 // 0x151f7c75 + == + assert // ARC4 prefix is valid + retsub + + +// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_bool_bytes(a: bytes) -> bytes: +verify_bool_bytes: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:335-336 + // @arc4.abimethod() + // public verify_bool_bytes(a: Bool): bytes { + proto 1 1 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:337 + // return a.bytes + frame_dig -1 + retsub + + +// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_bool_from_bytes(a: bytes) -> bytes: +verify_bool_from_bytes: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:339-340 + // @arc4.abimethod() + // public verify_bool_from_bytes(a: bytes): Bool { + proto 1 1 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:341 + // return Bool.fromBytes(a) + frame_dig -1 + 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 Bool.fromLog(a) + frame_dig -1 + extract 4 0 + frame_dig -1 + extract 0 4 + bytec_0 // 0x151f7c75 + == + assert // ARC4 prefix is valid + retsub diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json new file mode 100644 index 0000000..03885e9 --- /dev/null +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json @@ -0,0 +1,1137 @@ +{ + "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" + } + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSA4IDY0IDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NSAweDAwCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OAogICAgcHVzaGJ5dGVzcyAweDk2ZjE0MTE2IDB4ZWQ2NjYwOTYgMHgyY2EwMzUyYiAweDg1OTA3ZDQwIDB4NGViMmFmNGEgMHgyY2JlYzQ1YiAweDA3NjY2ZmQ5IDB4MzcwYmFiZDMgMHgyYjZiM2VmMCAweDI3ZTIxYTk4IDB4MzM5ZGE5N2MgMHg3ODk4ZWQ5NyAweDFmMTMwY2VjIDB4Yzc0ODY2NGUgMHhhMmJhYzE0YiAweDdhNDYwY2IxIDB4ZGNhYjFmMDEgMHg5N2Q5MDY0ZCAweGNlMDZjMmEwIDB4N2MxMWUzNzUgMHhkY2RiY2VlMCAweDc3YTRiNjhkIDB4NGY1NDA2MjYgMHgwOTVhZWQ0MSAweGRmNzhjZGM2IDB4ZTNiN2U5MTggMHg1NTMzNzAwOCAweDliYjFjZDY2IDB4ODE0ODRkOWQgMHg3OWU5Y2IwMyAweDlhMDNkZjEwIDB4ZDNmMGU0NGIgMHg2NzNkYjJiZCAweDk4MmRiMjMzIDB4YWZmYmRmMGUgMHg4ZTRhMzBmNyAweDI4OGFmNzZlIDB4OGJkODRhMDQgMHhmY2Q1NWUxZiAweDBmMTU3NGZlIDB4YjJjYjEzYmUgMHhkMDU5ZWVhNyAweDRjYzRjMTU3IDB4M2QxN2FjNmUgMHhmN2YzZDVmYyAweGY4YzhmOGQ1IDB4NDNmNzE2MmEgMHg0MmUwOTA3NSAweGQ5NTZmNTc1IDB4NmMwMTYwZGYgMHhhODkwMTUwYiAweDBiMmY0YzNmIDB4OWRiOWQzMjcgMHhlNGQ5NTBhMSAvLyBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfZXEoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9sdChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfbGUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2d0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9nZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9pbml0KGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9pbml0KGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9pbml0KGJ5dGVbXSlieXRlIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDMyIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhieXRlW10pYnl0ZSIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9sb2coYnl0ZVtdKWJ5dGUiLCBtZXRob2QgInZlcmlmeV91Zml4ZWRueG1fYnl0ZXModWZpeGVkMzJ4OClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXModWZpeGVkMjU2eDE2KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGJ5dGVbXSl1Zml4ZWQzMng4IiwgbWV0aG9kICJ2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMoYnl0ZVtdKXVmaXhlZDI1NngxNiIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMzJ4OCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMjU2eDE2IiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2luaXQoc3RyaW5nKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19hZGQoc3RyaW5nLHN0cmluZylzdHJpbmciLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZXEoc3RyaW5nLHN0cmluZylib29sIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2J5dGVzKHN0cmluZylieXRlW10iLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhieXRlW10pc3RyaW5nIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nKGJ5dGVbXSlzdHJpbmciLCBtZXRob2QgInZlcmlmeV9ib29sX2J5dGVzKGJvb2wpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2xvZyhieXRlW10pYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9lcV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbmVfcm91dGVANyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbmVfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbmVfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbHRfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbGVfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbGVfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ2Vfcm91dGVAMjcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAyOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2Vfcm91dGVAMzAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5faW5pdF9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9pbml0X3JvdXRlQDM0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZ19yb3V0ZUAzOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2xvZ19yb3V0ZUA0MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXNfcm91dGVANDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlc19yb3V0ZUA0NCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfYWRkX3JvdXRlQDQ4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19ieXRlc19yb3V0ZUA1MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9ieXRlc19yb3V0ZUA1MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZXFfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fZXFfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9ieXRlX2VxX3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9ieXRlX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX3VpbnRuX25lX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9uZV9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbHRfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbHRfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sZV9yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbGVfcm91dGVAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9ndF9yb3V0ZUAyMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ3QKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ3Rfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9nZV9yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ2Vfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9pbml0X3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5faW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfaW5pdF9yb3V0ZUAzNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXNfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfZnJvbV9sb2dfcm91dGVANDA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fYnl0ZXNfcm91dGVANDE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWZpeGVkbnhtX2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlc19yb3V0ZUA0MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfaW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19hZGRfcm91dGVANDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc3RyaW5nX2FkZAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19lcV9yb3V0ZUA0OToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fbG9nX3JvdXRlQDUyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2J5dGVzX3JvdXRlQDUzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Jvb2xfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NS02CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEKICAgIC8vIHJldHVybiBhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMy0xNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEtMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gcmV0dXJuIGFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIHJldHVybiBhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3LTM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MwogICAgLy8gcmV0dXJuIGFCeXRlLmVxdWFscyhiQnl0ZSkKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NS00NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0OQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MQogICAgLy8gcmV0dXJuICFhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1My01NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1NwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5CiAgICAvLyByZXR1cm4gIWFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgICEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxLTYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjcKICAgIC8vIHJldHVybiAhYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjktNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NQogICAgLy8gcmV0dXJuICFhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gcmV0dXJuICFhQnl0ZS5lcXVhbHMoYkJ5dGUpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUtODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMtOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5OQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPCBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxLTEwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDktMTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3LTExOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPCBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNS0xMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzMtMTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxLTE0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OS0xNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPD0gYlVpbnROLm5hdGl2ZQogICAgYjw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1Ny0xNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlIDw9IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NS0xNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczLTE3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc5CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEtMTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgaXRvYgogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OS0xOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPiBiVWludE4ubmF0aXZlCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTctMTk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMwogICAgLy8gcmV0dXJuIGFCeXRlLm5hdGl2ZSA+IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA1LTIwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMy0yMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxOQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gQmlnVWludChiVWludE4ubmF0aXZlKQogICAgYnRvaQogICAgaXRvYgogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEtMjIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID49IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5LTIzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+PSBiVWludE4ubmF0aXZlCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM3LTIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPj0gYkJ5dGUubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA+PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDUtMjQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OAogICAgLy8gcmV0dXJuIG5ldyBVaW50TjwzMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgcHVzaGludCA0IC8vIDQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIHB1c2hpbnQgNCAvLyA0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTAtMjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MjU2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTMKICAgIC8vIHJldHVybiBuZXcgVWludE48MjU2PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfaW5pdChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1LTI1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9pbml0KGE6IGJ5dGVzKTogQnl0ZSB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTgKICAgIC8vIHJldHVybiBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91aW50bl9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MC0yNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpOiBVaW50TjwzMj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYyCiAgICAvLyByZXR1cm4gVWludE4uZnJvbUJ5dGVzPFVpbnROPDMyPj4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjQtMjY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVWludE48MjU2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIHJldHVybiBVaW50Ti5mcm9tQnl0ZXM8VWludE48MjU2Pj4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY4LTI2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogQnl0ZSB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzAKICAgIC8vIHJldHVybiBCeXRlLmZyb21CeXRlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcyLTI3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fZnJvbV9sb2coYTogYnl0ZXMpOiBVaW50TjwzMj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc0CiAgICAvLyByZXR1cm4gVWludE4uZnJvbUxvZzxVaW50TjwzMj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYtMjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc4CiAgICAvLyByZXR1cm4gVWludE4uZnJvbUxvZzxVaW50TjwyNTY+PihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MC0yODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9sb2coYTogYnl0ZXMpOiBCeXRlIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MgogICAgLy8gcmV0dXJuIEJ5dGUuZnJvbUxvZyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWZpeGVkbnhtX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQtMjg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91Zml4ZWRueG1fYnl0ZXMoYTogVUZpeGVkTnhNPDMyLCA4Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NgogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4LTI4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzKGE6IFVGaXhlZE54TTwyNTYsIDE2Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MAogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Mi0yOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDMyLCA4PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTQKICAgIC8vIHJldHVybiBVRml4ZWROeE0uZnJvbUJ5dGVzPFVGaXhlZE54TTwzMiwgOD4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTYtMjk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlcyhhOiBieXRlcyk6IFVGaXhlZE54TTwyNTYsIDE2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTgKICAgIC8vIHJldHVybiBVRml4ZWROeE0uZnJvbUJ5dGVzPFVGaXhlZE54TTwyNTYsIDE2Pj4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwLTMwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDMyLCA4PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDIKICAgIC8vIHJldHVybiBVRml4ZWROeE0uZnJvbUxvZzxVRml4ZWROeE08MzIsIDg+PihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDQtMzA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpOiBVRml4ZWROeE08MjU2LCAxNj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA2CiAgICAvLyByZXR1cm4gVUZpeGVkTnhNLmZyb21Mb2c8VUZpeGVkTnhNPDI1NiwgMTY+PihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA4LTMwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2luaXQoYTogc3RyaW5nKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihgSGVsbG8sICR7YX1gKQogICAgcHVzaGJ5dGVzICJIZWxsbywgIgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMtMzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfYWRkKGE6IFN0ciwgYjogU3RyKTogU3RyIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5uYXRpdmUuY29uY2F0KGIubmF0aXZlKQogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE2CiAgICAvLyByZXR1cm4gbmV3IFN0cihyZXN1bHQpCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3N0cmluZ19lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgtMzE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZXEoYTogU3RyLCBiOiBTdHIpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMAogICAgLy8gcmV0dXJuIGEuZXF1YWxzKGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMi0zMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19ieXRlcyhhOiBzdHJpbmcpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG5ldyBTdHIoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjUKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjctMzI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjkKICAgIC8vIHJldHVybiBTdHIuZnJvbUJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMS0zMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2xvZyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzMKICAgIC8vIHJldHVybiBTdHIuZnJvbUxvZyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNS0zMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfYnl0ZXMoYTogQm9vbCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNwogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5LTM0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIHJldHVybiBCb29sLmZyb21CeXRlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0My0zNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfZnJvbV9sb2coYTogYnl0ZXMpOiBCb29sIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0NQogICAgLy8gcmV0dXJuIEJvb2wuZnJvbUxvZyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" + }, + "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" + } + } + ], + "networks": {} + }, + "bare_call_config": { + "no_op": "CREATE" + } +} \ 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 new file mode 100644 index 0000000..2bdc696 --- /dev/null +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.clear.teal @@ -0,0 +1,5 @@ +#pragma version 10 + +tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.clearStateProgram: + pushint 1 // 1 + return From 84c0741e2b5f0f230232bfa41e3213609bf21403 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 19 Nov 2024 15:17:41 +0800 Subject: [PATCH 57/85] chore: fix npm audit vulnerability --- .nsprc | 5 +++++ package.json | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.nsprc b/.nsprc index 2c63c08..840cbf7 100644 --- a/.nsprc +++ b/.nsprc @@ -1,2 +1,7 @@ { + "1100467": { + "active": true, + "notes": "Waiting for https://github.com/npm/cli/issues/7902 to be resolved", + "expiry": "2024-12-31" + } } diff --git a/package.json b/package.json index 6f0ecde..82439b4 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,8 @@ "semantic-release": "^24.1.2", "tsx": "4.19.1", "typescript": "^5.6.2", - "vitest": "2.1.2" + "vitest": "2.1.2", + "cross-spawn": "^7.0.6" }, "peerDependencies": { "tslib": "^2.6.2" From 07b8dbfab17e91d2173d77bb0b164f4849310811 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 26 Nov 2024 14:19:19 +0800 Subject: [PATCH 58/85] refactor: simplify type info passed to fromBytes and fromLog method --- tests/arc4/ufixednxm.spec.ts | 20 +++++++++---------- tests/arc4/uintn.spec.ts | 20 +++++++++---------- .../arc4-primitive-ops/contract.algo.ts | 16 +++++++-------- .../Arc4PrimitiveOpsContract.approval.teal | 16 +++++++-------- .../data/Arc4PrimitiveOpsContract.arc32.json | 2 +- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/tests/arc4/ufixednxm.spec.ts b/tests/arc4/ufixednxm.spec.ts index 6c0d3f5..42e37bd 100644 --- a/tests/arc4/ufixednxm.spec.ts +++ b/tests/arc4/ufixednxm.spec.ts @@ -62,7 +62,7 @@ describe('arc4.UFixedNxM', async () => { encodingUtil.bigIntToUint8Array(2n ** 32n - 1n), ])('create UFixedNxM<32,8> from bytes', async (value) => { const avmResult = await getAvmResult({ appClient }, 'verify_ufixednxm_from_bytes', value) - const result = UFixedNxM.fromBytes>(Bytes(value)) + const result = UFixedNxM.fromBytes<32, 8>(Bytes(value)) expect(result.native).toEqual(avmResult) }) @@ -75,7 +75,7 @@ describe('arc4.UFixedNxM', async () => { ])('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)) - const result = UFixedNxM.fromBytes>(Bytes(value)) + const result = UFixedNxM.fromBytes<32, 8>(Bytes(value)) expect(result.bytes).toEqual(value) }) @@ -88,7 +88,7 @@ describe('arc4.UFixedNxM', async () => { const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) const avmResult = await getAvmResult({ appClient }, 'verify_ufixednxm_from_log', logValue) - const result = UFixedNxM.fromLog>(Bytes(logValue)) + const result = UFixedNxM.fromLog<32, 8>(Bytes(logValue)) expect(avmResult).toEqual(expected) expect(result.native).toEqual(expected) }) @@ -99,7 +99,7 @@ describe('arc4.UFixedNxM', async () => { ])('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(() => UFixedNxM.fromLog>(Bytes(logValue))).toThrowError('ABI return prefix not found') + expect(() => UFixedNxM.fromLog<32, 8>(Bytes(logValue))).toThrowError('ABI return prefix not found') }) test.each([ @@ -111,7 +111,7 @@ describe('arc4.UFixedNxM', async () => { 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 = UFixedNxM.fromLog>(Bytes(logValue)) + const result = UFixedNxM.fromLog<32, 8>(Bytes(logValue)) expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) @@ -122,7 +122,7 @@ describe('arc4.UFixedNxM', async () => { encodingUtil.bigIntToUint8Array(2n ** 256n - 1n), ])('create UFixedNxM<256,16> from bytes', async (value) => { const avmResult = await getAvmResult({ appClient }, 'verify_bigufixednxm_from_bytes', value) - const result = UFixedNxM.fromBytes>(Bytes(value)) + const result = UFixedNxM.fromBytes<256, 16>(Bytes(value)) expect(result.native).toEqual(avmResult) }) @@ -135,7 +135,7 @@ describe('arc4.UFixedNxM', async () => { ])('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)) - const result = UFixedNxM.fromBytes>(Bytes(value)) + const result = UFixedNxM.fromBytes<256, 16>(Bytes(value)) expect(result.bytes).toEqual(value) }) @@ -148,7 +148,7 @@ describe('arc4.UFixedNxM', async () => { const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) const avmResult = await getAvmResult({ appClient }, 'verify_bigufixednxm_from_log', logValue) - const result = UFixedNxM.fromLog>(Bytes(logValue)) + const result = UFixedNxM.fromLog<256, 16>(Bytes(logValue)) expect(avmResult).toEqual(expected) expect(result.native).toEqual(expected) }) @@ -159,7 +159,7 @@ describe('arc4.UFixedNxM', async () => { ])('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(() => UFixedNxM.fromLog>(Bytes(logValue))).toThrowError('ABI return prefix not found') + expect(() => UFixedNxM.fromLog<256, 16>(Bytes(logValue))).toThrowError('ABI return prefix not found') }) test.each([ @@ -173,7 +173,7 @@ describe('arc4.UFixedNxM', async () => { invalidBytesLengthError(256), ) - const result = UFixedNxM.fromLog>(Bytes(logValue)) + const result = UFixedNxM.fromLog<256, 16>(Bytes(logValue)) expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) }) diff --git a/tests/arc4/uintn.spec.ts b/tests/arc4/uintn.spec.ts index dd9a48c..d18b7da 100644 --- a/tests/arc4/uintn.spec.ts +++ b/tests/arc4/uintn.spec.ts @@ -152,7 +152,7 @@ describe('arc4.UintN', async () => { encodingUtil.bigIntToUint8Array(2n ** 32n - 1n), ])('create UintN<32> from bytes', async (value) => { const avmResult = await getAvmResult({ appClient }, 'verify_uintn_from_bytes', value) - const result = UintN.fromBytes>(Bytes(value)) + const result = UintN.fromBytes<32>(Bytes(value)) expect(result.native).toEqual(avmResult) }) @@ -165,7 +165,7 @@ describe('arc4.UintN', async () => { ])('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)) - const result = UintN.fromBytes>(Bytes(value)) + const result = UintN.fromBytes<32>(Bytes(value)) expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) @@ -176,7 +176,7 @@ describe('arc4.UintN', async () => { encodingUtil.bigIntToUint8Array(2n ** 256n - 1n), ])('create UintN<256> from bytes', async (value) => { const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_from_bytes', value) - const result = UintN.fromBytes>(Bytes(value)) + const result = UintN.fromBytes<256>(Bytes(value)) expect(result.native).toEqual(avmResult) }) @@ -189,7 +189,7 @@ describe('arc4.UintN', async () => { ])('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)) - const result = UintN.fromBytes>(Bytes(value)) + const result = UintN.fromBytes<256>(Bytes(value)) expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) @@ -202,7 +202,7 @@ describe('arc4.UintN', async () => { const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) const avmResult = await getAvmResult({ appClient }, 'verify_uintn_from_log', logValue) - const result = UintN.fromLog>(Bytes(logValue)) + const result = UintN.fromLog<32>(Bytes(logValue)) expect(avmResult).toEqual(expected) expect(result.native).toEqual(expected) }) @@ -213,7 +213,7 @@ describe('arc4.UintN', async () => { ])('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(() => UintN.fromLog>(Bytes(logValue))).toThrowError('ABI return prefix not found') + expect(() => UintN.fromLog<32>(Bytes(logValue))).toThrowError('ABI return prefix not found') }) test.each([ @@ -225,7 +225,7 @@ describe('arc4.UintN', async () => { 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 = UintN.fromLog>(Bytes(logValue)) + const result = UintN.fromLog<32>(Bytes(logValue)) expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) @@ -238,7 +238,7 @@ describe('arc4.UintN', async () => { const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_from_log', logValue) - const result = UintN.fromLog>(Bytes(logValue)) + const result = UintN.fromLog<256>(Bytes(logValue)) expect(avmResult).toEqual(expected) expect(result.native).toEqual(expected) }) @@ -249,7 +249,7 @@ describe('arc4.UintN', async () => { ])('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(() => UintN.fromLog>(Bytes(logValue))).toThrowError('ABI return prefix not found') + expect(() => UintN.fromLog<256>(Bytes(logValue))).toThrowError('ABI return prefix not found') }) test.each([ @@ -261,7 +261,7 @@ describe('arc4.UintN', async () => { 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 = UintN.fromLog>(Bytes(logValue)) + const result = UintN.fromLog<256>(Bytes(logValue)) expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) }) diff --git a/tests/artifacts/arc4-primitive-ops/contract.algo.ts b/tests/artifacts/arc4-primitive-ops/contract.algo.ts index 5c8a5ba..42a7a93 100644 --- a/tests/artifacts/arc4-primitive-ops/contract.algo.ts +++ b/tests/artifacts/arc4-primitive-ops/contract.algo.ts @@ -259,11 +259,11 @@ export class Arc4PrimitiveOpsContract extends Contract { } @arc4.abimethod() public verify_uintn_from_bytes(a: bytes): UintN<32> { - return UintN.fromBytes>(a) + return UintN.fromBytes<32>(a) } @arc4.abimethod() public verify_biguintn_from_bytes(a: bytes): UintN<256> { - return UintN.fromBytes>(a) + return UintN.fromBytes<256>(a) } @arc4.abimethod() public verify_byte_from_bytes(a: bytes): Byte { @@ -271,11 +271,11 @@ export class Arc4PrimitiveOpsContract extends Contract { } @arc4.abimethod() public verify_uintn_from_log(a: bytes): UintN<32> { - return UintN.fromLog>(a) + return UintN.fromLog<32>(a) } @arc4.abimethod() public verify_biguintn_from_log(a: bytes): UintN<256> { - return UintN.fromLog>(a) + return UintN.fromLog<256>(a) } @arc4.abimethod() public verify_byte_from_log(a: bytes): Byte { @@ -291,19 +291,19 @@ export class Arc4PrimitiveOpsContract extends Contract { } @arc4.abimethod() public verify_ufixednxm_from_bytes(a: bytes): UFixedNxM<32, 8> { - return UFixedNxM.fromBytes>(a) + return UFixedNxM.fromBytes<32, 8>(a) } @arc4.abimethod() public verify_bigufixednxm_from_bytes(a: bytes): UFixedNxM<256, 16> { - return UFixedNxM.fromBytes>(a) + return UFixedNxM.fromBytes<256, 16>(a) } @arc4.abimethod() public verify_ufixednxm_from_log(a: bytes): UFixedNxM<32, 8> { - return UFixedNxM.fromLog>(a) + return UFixedNxM.fromLog<32, 8>(a) } @arc4.abimethod() public verify_bigufixednxm_from_log(a: bytes): UFixedNxM<256, 16> { - return UFixedNxM.fromLog>(a) + return UFixedNxM.fromLog<256, 16>(a) } @arc4.abimethod() public verify_string_init(a: string): Str { diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal index c02361b..26a7070 100644 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal @@ -2575,7 +2575,7 @@ verify_uintn_from_bytes: // public verify_uintn_from_bytes(a: bytes): UintN<32> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:262 - // return UintN.fromBytes>(a) + // return UintN.fromBytes<32>(a) frame_dig -1 retsub @@ -2587,7 +2587,7 @@ verify_biguintn_from_bytes: // public verify_biguintn_from_bytes(a: bytes): UintN<256> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:266 - // return UintN.fromBytes>(a) + // return UintN.fromBytes<256>(a) frame_dig -1 retsub @@ -2611,7 +2611,7 @@ verify_uintn_from_log: // public verify_uintn_from_log(a: bytes): UintN<32> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:274 - // return UintN.fromLog>(a) + // return UintN.fromLog<32>(a) frame_dig -1 extract 4 0 frame_dig -1 @@ -2629,7 +2629,7 @@ verify_biguintn_from_log: // public verify_biguintn_from_log(a: bytes): UintN<256> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:278 - // return UintN.fromLog>(a) + // return UintN.fromLog<256>(a) frame_dig -1 extract 4 0 frame_dig -1 @@ -2689,7 +2689,7 @@ verify_ufixednxm_from_bytes: // public verify_ufixednxm_from_bytes(a: bytes): UFixedNxM<32, 8> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:294 - // return UFixedNxM.fromBytes>(a) + // return UFixedNxM.fromBytes<32, 8>(a) frame_dig -1 retsub @@ -2701,7 +2701,7 @@ verify_bigufixednxm_from_bytes: // public verify_bigufixednxm_from_bytes(a: bytes): UFixedNxM<256, 16> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:298 - // return UFixedNxM.fromBytes>(a) + // return UFixedNxM.fromBytes<256, 16>(a) frame_dig -1 retsub @@ -2713,7 +2713,7 @@ verify_ufixednxm_from_log: // public verify_ufixednxm_from_log(a: bytes): UFixedNxM<32, 8> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:302 - // return UFixedNxM.fromLog>(a) + // return UFixedNxM.fromLog<32, 8>(a) frame_dig -1 extract 4 0 frame_dig -1 @@ -2731,7 +2731,7 @@ verify_bigufixednxm_from_log: // public verify_bigufixednxm_from_log(a: bytes): UFixedNxM<256, 16> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:306 - // return UFixedNxM.fromLog>(a) + // return UFixedNxM.fromLog<256, 16>(a) frame_dig -1 extract 4 0 frame_dig -1 diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json index 03885e9..11a0c0c 100644 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json @@ -272,7 +272,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSA4IDY0IDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NSAweDAwCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OAogICAgcHVzaGJ5dGVzcyAweDk2ZjE0MTE2IDB4ZWQ2NjYwOTYgMHgyY2EwMzUyYiAweDg1OTA3ZDQwIDB4NGViMmFmNGEgMHgyY2JlYzQ1YiAweDA3NjY2ZmQ5IDB4MzcwYmFiZDMgMHgyYjZiM2VmMCAweDI3ZTIxYTk4IDB4MzM5ZGE5N2MgMHg3ODk4ZWQ5NyAweDFmMTMwY2VjIDB4Yzc0ODY2NGUgMHhhMmJhYzE0YiAweDdhNDYwY2IxIDB4ZGNhYjFmMDEgMHg5N2Q5MDY0ZCAweGNlMDZjMmEwIDB4N2MxMWUzNzUgMHhkY2RiY2VlMCAweDc3YTRiNjhkIDB4NGY1NDA2MjYgMHgwOTVhZWQ0MSAweGRmNzhjZGM2IDB4ZTNiN2U5MTggMHg1NTMzNzAwOCAweDliYjFjZDY2IDB4ODE0ODRkOWQgMHg3OWU5Y2IwMyAweDlhMDNkZjEwIDB4ZDNmMGU0NGIgMHg2NzNkYjJiZCAweDk4MmRiMjMzIDB4YWZmYmRmMGUgMHg4ZTRhMzBmNyAweDI4OGFmNzZlIDB4OGJkODRhMDQgMHhmY2Q1NWUxZiAweDBmMTU3NGZlIDB4YjJjYjEzYmUgMHhkMDU5ZWVhNyAweDRjYzRjMTU3IDB4M2QxN2FjNmUgMHhmN2YzZDVmYyAweGY4YzhmOGQ1IDB4NDNmNzE2MmEgMHg0MmUwOTA3NSAweGQ5NTZmNTc1IDB4NmMwMTYwZGYgMHhhODkwMTUwYiAweDBiMmY0YzNmIDB4OWRiOWQzMjcgMHhlNGQ5NTBhMSAvLyBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfZXEoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9sdChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfbGUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2d0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9nZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9pbml0KGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9pbml0KGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9pbml0KGJ5dGVbXSlieXRlIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDMyIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhieXRlW10pYnl0ZSIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9sb2coYnl0ZVtdKWJ5dGUiLCBtZXRob2QgInZlcmlmeV91Zml4ZWRueG1fYnl0ZXModWZpeGVkMzJ4OClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXModWZpeGVkMjU2eDE2KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGJ5dGVbXSl1Zml4ZWQzMng4IiwgbWV0aG9kICJ2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMoYnl0ZVtdKXVmaXhlZDI1NngxNiIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMzJ4OCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMjU2eDE2IiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2luaXQoc3RyaW5nKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19hZGQoc3RyaW5nLHN0cmluZylzdHJpbmciLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZXEoc3RyaW5nLHN0cmluZylib29sIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2J5dGVzKHN0cmluZylieXRlW10iLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhieXRlW10pc3RyaW5nIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nKGJ5dGVbXSlzdHJpbmciLCBtZXRob2QgInZlcmlmeV9ib29sX2J5dGVzKGJvb2wpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2xvZyhieXRlW10pYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9lcV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbmVfcm91dGVANyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbmVfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbmVfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbHRfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbGVfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbGVfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ2Vfcm91dGVAMjcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAyOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2Vfcm91dGVAMzAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5faW5pdF9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9pbml0X3JvdXRlQDM0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZ19yb3V0ZUAzOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2xvZ19yb3V0ZUA0MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXNfcm91dGVANDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlc19yb3V0ZUA0NCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfYWRkX3JvdXRlQDQ4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19ieXRlc19yb3V0ZUA1MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9ieXRlc19yb3V0ZUA1MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZXFfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fZXFfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9ieXRlX2VxX3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9ieXRlX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX3VpbnRuX25lX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9uZV9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbHRfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbHRfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sZV9yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbGVfcm91dGVAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9ndF9yb3V0ZUAyMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ3QKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ3Rfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9nZV9yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ2Vfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9pbml0X3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5faW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfaW5pdF9yb3V0ZUAzNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXNfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfZnJvbV9sb2dfcm91dGVANDA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fYnl0ZXNfcm91dGVANDE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWZpeGVkbnhtX2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlc19yb3V0ZUA0MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfaW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19hZGRfcm91dGVANDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc3RyaW5nX2FkZAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19lcV9yb3V0ZUA0OToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fbG9nX3JvdXRlQDUyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2J5dGVzX3JvdXRlQDUzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Jvb2xfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NS02CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEKICAgIC8vIHJldHVybiBhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMy0xNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEtMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gcmV0dXJuIGFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIHJldHVybiBhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3LTM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MwogICAgLy8gcmV0dXJuIGFCeXRlLmVxdWFscyhiQnl0ZSkKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NS00NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0OQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MQogICAgLy8gcmV0dXJuICFhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1My01NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1NwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5CiAgICAvLyByZXR1cm4gIWFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgICEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxLTYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjcKICAgIC8vIHJldHVybiAhYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjktNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NQogICAgLy8gcmV0dXJuICFhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gcmV0dXJuICFhQnl0ZS5lcXVhbHMoYkJ5dGUpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUtODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMtOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5OQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPCBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxLTEwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDktMTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3LTExOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPCBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNS0xMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzMtMTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxLTE0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OS0xNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPD0gYlVpbnROLm5hdGl2ZQogICAgYjw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1Ny0xNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlIDw9IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NS0xNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczLTE3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc5CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEtMTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgaXRvYgogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OS0xOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPiBiVWludE4ubmF0aXZlCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTctMTk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMwogICAgLy8gcmV0dXJuIGFCeXRlLm5hdGl2ZSA+IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA1LTIwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMy0yMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxOQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gQmlnVWludChiVWludE4ubmF0aXZlKQogICAgYnRvaQogICAgaXRvYgogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEtMjIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID49IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5LTIzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+PSBiVWludE4ubmF0aXZlCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM3LTIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPj0gYkJ5dGUubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA+PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDUtMjQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OAogICAgLy8gcmV0dXJuIG5ldyBVaW50TjwzMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgcHVzaGludCA0IC8vIDQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIHB1c2hpbnQgNCAvLyA0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTAtMjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MjU2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTMKICAgIC8vIHJldHVybiBuZXcgVWludE48MjU2PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfaW5pdChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1LTI1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9pbml0KGE6IGJ5dGVzKTogQnl0ZSB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTgKICAgIC8vIHJldHVybiBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91aW50bl9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MC0yNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpOiBVaW50TjwzMj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYyCiAgICAvLyByZXR1cm4gVWludE4uZnJvbUJ5dGVzPFVpbnROPDMyPj4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjQtMjY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVWludE48MjU2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIHJldHVybiBVaW50Ti5mcm9tQnl0ZXM8VWludE48MjU2Pj4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY4LTI2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogQnl0ZSB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzAKICAgIC8vIHJldHVybiBCeXRlLmZyb21CeXRlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcyLTI3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fZnJvbV9sb2coYTogYnl0ZXMpOiBVaW50TjwzMj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc0CiAgICAvLyByZXR1cm4gVWludE4uZnJvbUxvZzxVaW50TjwzMj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYtMjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc4CiAgICAvLyByZXR1cm4gVWludE4uZnJvbUxvZzxVaW50TjwyNTY+PihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MC0yODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9sb2coYTogYnl0ZXMpOiBCeXRlIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MgogICAgLy8gcmV0dXJuIEJ5dGUuZnJvbUxvZyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWZpeGVkbnhtX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQtMjg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91Zml4ZWRueG1fYnl0ZXMoYTogVUZpeGVkTnhNPDMyLCA4Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NgogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4LTI4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzKGE6IFVGaXhlZE54TTwyNTYsIDE2Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MAogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Mi0yOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDMyLCA4PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTQKICAgIC8vIHJldHVybiBVRml4ZWROeE0uZnJvbUJ5dGVzPFVGaXhlZE54TTwzMiwgOD4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTYtMjk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlcyhhOiBieXRlcyk6IFVGaXhlZE54TTwyNTYsIDE2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTgKICAgIC8vIHJldHVybiBVRml4ZWROeE0uZnJvbUJ5dGVzPFVGaXhlZE54TTwyNTYsIDE2Pj4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwLTMwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDMyLCA4PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDIKICAgIC8vIHJldHVybiBVRml4ZWROeE0uZnJvbUxvZzxVRml4ZWROeE08MzIsIDg+PihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDQtMzA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpOiBVRml4ZWROeE08MjU2LCAxNj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA2CiAgICAvLyByZXR1cm4gVUZpeGVkTnhNLmZyb21Mb2c8VUZpeGVkTnhNPDI1NiwgMTY+PihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA4LTMwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2luaXQoYTogc3RyaW5nKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihgSGVsbG8sICR7YX1gKQogICAgcHVzaGJ5dGVzICJIZWxsbywgIgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMtMzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfYWRkKGE6IFN0ciwgYjogU3RyKTogU3RyIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5uYXRpdmUuY29uY2F0KGIubmF0aXZlKQogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE2CiAgICAvLyByZXR1cm4gbmV3IFN0cihyZXN1bHQpCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3N0cmluZ19lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgtMzE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZXEoYTogU3RyLCBiOiBTdHIpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMAogICAgLy8gcmV0dXJuIGEuZXF1YWxzKGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMi0zMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19ieXRlcyhhOiBzdHJpbmcpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG5ldyBTdHIoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjUKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjctMzI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjkKICAgIC8vIHJldHVybiBTdHIuZnJvbUJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMS0zMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2xvZyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzMKICAgIC8vIHJldHVybiBTdHIuZnJvbUxvZyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNS0zMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfYnl0ZXMoYTogQm9vbCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNwogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5LTM0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIHJldHVybiBCb29sLmZyb21CeXRlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0My0zNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfZnJvbV9sb2coYTogYnl0ZXMpOiBCb29sIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0NQogICAgLy8gcmV0dXJuIEJvb2wuZnJvbUxvZyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSA4IDY0IDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NSAweDAwCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OAogICAgcHVzaGJ5dGVzcyAweDk2ZjE0MTE2IDB4ZWQ2NjYwOTYgMHgyY2EwMzUyYiAweDg1OTA3ZDQwIDB4NGViMmFmNGEgMHgyY2JlYzQ1YiAweDA3NjY2ZmQ5IDB4MzcwYmFiZDMgMHgyYjZiM2VmMCAweDI3ZTIxYTk4IDB4MzM5ZGE5N2MgMHg3ODk4ZWQ5NyAweDFmMTMwY2VjIDB4Yzc0ODY2NGUgMHhhMmJhYzE0YiAweDdhNDYwY2IxIDB4ZGNhYjFmMDEgMHg5N2Q5MDY0ZCAweGNlMDZjMmEwIDB4N2MxMWUzNzUgMHhkY2RiY2VlMCAweDc3YTRiNjhkIDB4NGY1NDA2MjYgMHgwOTVhZWQ0MSAweGRmNzhjZGM2IDB4ZTNiN2U5MTggMHg1NTMzNzAwOCAweDliYjFjZDY2IDB4ODE0ODRkOWQgMHg3OWU5Y2IwMyAweDlhMDNkZjEwIDB4ZDNmMGU0NGIgMHg2NzNkYjJiZCAweDk4MmRiMjMzIDB4YWZmYmRmMGUgMHg4ZTRhMzBmNyAweDI4OGFmNzZlIDB4OGJkODRhMDQgMHhmY2Q1NWUxZiAweDBmMTU3NGZlIDB4YjJjYjEzYmUgMHhkMDU5ZWVhNyAweDRjYzRjMTU3IDB4M2QxN2FjNmUgMHhmN2YzZDVmYyAweGY4YzhmOGQ1IDB4NDNmNzE2MmEgMHg0MmUwOTA3NSAweGQ5NTZmNTc1IDB4NmMwMTYwZGYgMHhhODkwMTUwYiAweDBiMmY0YzNmIDB4OWRiOWQzMjcgMHhlNGQ5NTBhMSAvLyBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfZXEoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9sdChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfbGUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2d0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9nZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9pbml0KGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9pbml0KGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9pbml0KGJ5dGVbXSlieXRlIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDMyIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhieXRlW10pYnl0ZSIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9sb2coYnl0ZVtdKWJ5dGUiLCBtZXRob2QgInZlcmlmeV91Zml4ZWRueG1fYnl0ZXModWZpeGVkMzJ4OClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXModWZpeGVkMjU2eDE2KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGJ5dGVbXSl1Zml4ZWQzMng4IiwgbWV0aG9kICJ2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMoYnl0ZVtdKXVmaXhlZDI1NngxNiIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMzJ4OCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMjU2eDE2IiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2luaXQoc3RyaW5nKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19hZGQoc3RyaW5nLHN0cmluZylzdHJpbmciLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZXEoc3RyaW5nLHN0cmluZylib29sIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2J5dGVzKHN0cmluZylieXRlW10iLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhieXRlW10pc3RyaW5nIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nKGJ5dGVbXSlzdHJpbmciLCBtZXRob2QgInZlcmlmeV9ib29sX2J5dGVzKGJvb2wpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2xvZyhieXRlW10pYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9lcV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbmVfcm91dGVANyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbmVfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbmVfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbHRfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbGVfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbGVfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ2Vfcm91dGVAMjcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAyOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2Vfcm91dGVAMzAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5faW5pdF9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9pbml0X3JvdXRlQDM0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZ19yb3V0ZUAzOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2xvZ19yb3V0ZUA0MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXNfcm91dGVANDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlc19yb3V0ZUA0NCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfYWRkX3JvdXRlQDQ4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19ieXRlc19yb3V0ZUA1MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9ieXRlc19yb3V0ZUA1MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZXFfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fZXFfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9ieXRlX2VxX3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9ieXRlX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX3VpbnRuX25lX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9uZV9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbHRfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbHRfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sZV9yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbGVfcm91dGVAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9ndF9yb3V0ZUAyMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ3QKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ3Rfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9nZV9yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ2Vfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9pbml0X3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5faW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfaW5pdF9yb3V0ZUAzNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXNfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfZnJvbV9sb2dfcm91dGVANDA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fYnl0ZXNfcm91dGVANDE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWZpeGVkbnhtX2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlc19yb3V0ZUA0MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfaW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19hZGRfcm91dGVANDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc3RyaW5nX2FkZAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19lcV9yb3V0ZUA0OToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fbG9nX3JvdXRlQDUyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2J5dGVzX3JvdXRlQDUzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Jvb2xfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NS02CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEKICAgIC8vIHJldHVybiBhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMy0xNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEtMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gcmV0dXJuIGFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIHJldHVybiBhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3LTM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MwogICAgLy8gcmV0dXJuIGFCeXRlLmVxdWFscyhiQnl0ZSkKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NS00NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0OQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MQogICAgLy8gcmV0dXJuICFhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1My01NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1NwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5CiAgICAvLyByZXR1cm4gIWFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgICEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxLTYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjcKICAgIC8vIHJldHVybiAhYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjktNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NQogICAgLy8gcmV0dXJuICFhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gcmV0dXJuICFhQnl0ZS5lcXVhbHMoYkJ5dGUpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUtODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMtOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5OQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPCBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxLTEwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDktMTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3LTExOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPCBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNS0xMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzMtMTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxLTE0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OS0xNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPD0gYlVpbnROLm5hdGl2ZQogICAgYjw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1Ny0xNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlIDw9IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NS0xNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczLTE3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc5CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEtMTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgaXRvYgogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OS0xOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPiBiVWludE4ubmF0aXZlCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTctMTk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMwogICAgLy8gcmV0dXJuIGFCeXRlLm5hdGl2ZSA+IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA1LTIwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMy0yMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxOQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gQmlnVWludChiVWludE4ubmF0aXZlKQogICAgYnRvaQogICAgaXRvYgogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEtMjIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID49IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5LTIzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+PSBiVWludE4ubmF0aXZlCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM3LTIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPj0gYkJ5dGUubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA+PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDUtMjQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OAogICAgLy8gcmV0dXJuIG5ldyBVaW50TjwzMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgcHVzaGludCA0IC8vIDQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIHB1c2hpbnQgNCAvLyA0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTAtMjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MjU2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTMKICAgIC8vIHJldHVybiBuZXcgVWludE48MjU2PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfaW5pdChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1LTI1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9pbml0KGE6IGJ5dGVzKTogQnl0ZSB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTgKICAgIC8vIHJldHVybiBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91aW50bl9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MC0yNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpOiBVaW50TjwzMj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYyCiAgICAvLyByZXR1cm4gVWludE4uZnJvbUJ5dGVzPDMyPihhKQogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NC0yNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpOiBVaW50TjwyNTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gcmV0dXJuIFVpbnROLmZyb21CeXRlczwyNTY+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OC0yNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcwCiAgICAvLyByZXR1cm4gQnl0ZS5mcm9tQnl0ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VpbnRuX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3Mi0yNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NAogICAgLy8gcmV0dXJuIFVpbnROLmZyb21Mb2c8MzI+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYtMjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc4CiAgICAvLyByZXR1cm4gVWludE4uZnJvbUxvZzwyNTY+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2Zyb21fbG9nKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2J5dGVfZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgwLTI4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9mcm9tX2xvZyhhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgyCiAgICAvLyByZXR1cm4gQnl0ZS5mcm9tTG9nKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91Zml4ZWRueG1fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWZpeGVkbnhtX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NC0yODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9ieXRlcyhhOiBVRml4ZWROeE08MzIsIDg+KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg2CiAgICAvLyByZXR1cm4gYS5ieXRlcwogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgtMjg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXMoYTogVUZpeGVkTnhNPDI1NiwgMTY+KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkwCiAgICAvLyByZXR1cm4gYS5ieXRlcwogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkyLTI5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXMoYTogYnl0ZXMpOiBVRml4ZWROeE08MzIsIDg+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NAogICAgLy8gcmV0dXJuIFVGaXhlZE54TS5mcm9tQnl0ZXM8MzIsIDg+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTYtMjk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlcyhhOiBieXRlcyk6IFVGaXhlZE54TTwyNTYsIDE2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTgKICAgIC8vIHJldHVybiBVRml4ZWROeE0uZnJvbUJ5dGVzPDI1NiwgMTY+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMC0zMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwzMiwgOD4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAyCiAgICAvLyByZXR1cm4gVUZpeGVkTnhNLmZyb21Mb2c8MzIsIDg+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNC0zMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwyNTYsIDE2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDYKICAgIC8vIHJldHVybiBVRml4ZWROeE0uZnJvbUxvZzwyNTYsIDE2PihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA4LTMwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2luaXQoYTogc3RyaW5nKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihgSGVsbG8sICR7YX1gKQogICAgcHVzaGJ5dGVzICJIZWxsbywgIgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMtMzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfYWRkKGE6IFN0ciwgYjogU3RyKTogU3RyIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5uYXRpdmUuY29uY2F0KGIubmF0aXZlKQogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE2CiAgICAvLyByZXR1cm4gbmV3IFN0cihyZXN1bHQpCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3N0cmluZ19lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgtMzE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZXEoYTogU3RyLCBiOiBTdHIpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMAogICAgLy8gcmV0dXJuIGEuZXF1YWxzKGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMi0zMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19ieXRlcyhhOiBzdHJpbmcpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG5ldyBTdHIoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjUKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjctMzI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjkKICAgIC8vIHJldHVybiBTdHIuZnJvbUJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMS0zMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2xvZyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzMKICAgIC8vIHJldHVybiBTdHIuZnJvbUxvZyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNS0zMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfYnl0ZXMoYTogQm9vbCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNwogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5LTM0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIHJldHVybiBCb29sLmZyb21CeXRlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0My0zNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfZnJvbV9sb2coYTogYnl0ZXMpOiBCb29sIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0NQogICAgLy8gcmV0dXJuIEJvb2wuZnJvbUxvZyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" }, "state": { From f95312eadc497ec31c4355d2859b5370b0995dd1 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Wed, 27 Nov 2024 13:16:49 +0800 Subject: [PATCH 59/85] refactor: stop importing NativeForArc4Int and CompatForArc4Int as they are not exported by algo-ts to prevent confustion for the user --- src/impl/encoded-types.ts | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/impl/encoded-types.ts b/src/impl/encoded-types.ts index 119b4f1..d47f58a 100644 --- a/src/impl/encoded-types.ts +++ b/src/impl/encoded-types.ts @@ -1,14 +1,5 @@ -import { Bytes, bytes, internal, StringCompat } from '@algorandfoundation/algorand-typescript' -import { - BitSize, - Bool, - Byte, - CompatForArc4Int, - NativeForArc4Int, - Str, - UFixedNxM, - UintN, -} from '@algorandfoundation/algorand-typescript/arc4' +import { BigUintCompat, Bytes, bytes, internal, StringCompat, Uint64Compat } from '@algorandfoundation/algorand-typescript' +import { BitSize, Bool, Byte, Str, UFixedNxM, UintN } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import assert from 'assert' import { ABI_RETURN_VALUE_LOG_PREFIX, BITS_IN_BYTE, UINT64_SIZE } from '../constants' @@ -20,6 +11,7 @@ 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)) +type CompatForArc4Int = N extends 8 | 16 | 32 | 64 ? Uint64Compat : BigUintCompat export class UintNImpl extends UintN { private value: Uint8Array private bitSize: N @@ -39,9 +31,9 @@ export class UintNImpl extends UintN { this.value = encodingUtil.bigIntToUint8Array(bigIntValue, maxBytesLength(this.bitSize)) } - get native(): NativeForArc4Int { + get native() { const bigIntValue = encodingUtil.uint8ArrayToBigInt(this.value) - return (this.bitSize <= UINT64_SIZE ? asUint64(bigIntValue) : asBigUint(bigIntValue)) as NativeForArc4Int + return (this.bitSize <= UINT64_SIZE ? asUint64(bigIntValue) : asBigUint(bigIntValue)) as UintN['native'] } get bytes(): bytes { @@ -85,9 +77,9 @@ export class UFixedNxMImpl extends UFixedNx this.value = encodingUtil.bigIntToUint8Array(bigIntValue, maxBytesLength(this.bitSize)) } - get native(): NativeForArc4Int { + get native() { const bigIntValue = encodingUtil.uint8ArrayToBigInt(this.value) - return (this.bitSize <= UINT64_SIZE ? asUint64(bigIntValue) : asBigUint(bigIntValue)) as NativeForArc4Int + return (this.bitSize <= UINT64_SIZE ? asUint64(bigIntValue) : asBigUint(bigIntValue)) as UFixedNxM['native'] } get bytes(): bytes { @@ -120,7 +112,7 @@ export class ByteImpl extends Byte { this.value = new UintNImpl<8>(typeInfoString, v) } - get native(): NativeForArc4Int<8> { + get native() { return this.value.native } From 162d6381e366cfb59a01a956d54b808d2a42d07e Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 28 Nov 2024 10:59:14 +0800 Subject: [PATCH 60/85] refactor: import ptypes namespace instead of individual types --- .nsprc | 8 +-- package.json | 2 +- src/test-transformer/node-factory.ts | 4 +- src/test-transformer/visitors.ts | 89 ++++++++++++---------------- 4 files changed, 43 insertions(+), 60 deletions(-) diff --git a/.nsprc b/.nsprc index 840cbf7..0967ef4 100644 --- a/.nsprc +++ b/.nsprc @@ -1,7 +1 @@ -{ - "1100467": { - "active": true, - "notes": "Waiting for https://github.com/npm/cli/issues/7902 to be resolved", - "expiry": "2024-12-31" - } -} +{} diff --git a/package.json b/package.json index 82439b4..6f873fb 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "tsx": "4.19.1", "typescript": "^5.6.2", "vitest": "2.1.2", - "cross-spawn": "^7.0.6" + "cross-spawn": "7.0.6" }, "peerDependencies": { "tslib": "^2.6.2" diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 0ce7252..88eed2f 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -1,4 +1,4 @@ -import { FunctionPType } from '@algorandfoundation/puya-ts' +import { ptypes } from '@algorandfoundation/puya-ts' import ts from 'typescript' import { TypeInfo } from '../encoders' import type { DeliberateAny } from '../typescript-helpers' @@ -48,7 +48,7 @@ export const nodeFactory = { ) }, - attachMetaData(classIdentifier: ts.Identifier, method: ts.MethodDeclaration, functionType: FunctionPType) { + attachMetaData(classIdentifier: ts.Identifier, method: ts.MethodDeclaration, functionType: ptypes.FunctionPType) { const methodName = getPropertyNameAsString(method.name) const metadata = factory.createObjectLiteralExpression([ factory.createPropertyAssignment('methodName', methodName), diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index 2d5b07d..093f248 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -1,23 +1,4 @@ -import { - anyPType, - ARC4BooleanType, - ARC4StringType, - ARC4StructType, - ARC4TupleType, - BoxMapPType, - BoxPType, - ContractClassPType, - DynamicArrayType, - FunctionPType, - GlobalStateType, - LocalStateType, - PType, - SourceLocation, - StaticArrayType, - TypeResolver, - UFixedNxMType, - UintNType, -} from '@algorandfoundation/puya-ts' +import { ptypes, SourceLocation, TypeResolver } from '@algorandfoundation/puya-ts' import ts from 'typescript' import type { TypeInfo } from '../encoders' import { instanceOfAny } from '../typescript-helpers' @@ -33,7 +14,7 @@ const { factory } = ts type VisitorHelper = { additionalStatements: ts.Statement[] - resolveType(node: ts.Node): PType + resolveType(node: ts.Node): ptypes.PType sourceLocation(node: ts.Node): SourceLocation } @@ -49,11 +30,11 @@ export class SourceFileVisitor { this.helper = { additionalStatements: [], - resolveType(node: ts.Node): PType { + resolveType(node: ts.Node): ptypes.PType { try { return typeResolver.resolve(node, this.sourceLocation(node)) } catch { - return anyPType + return ptypes.anyPType } }, sourceLocation(node: ts.Node): SourceLocation { @@ -106,7 +87,7 @@ class ExpressionVisitor { let type = this.helper.resolveType(node) // `voted = LocalState()` is resolved to FunctionPType with returnType LocalState - if (type instanceof FunctionPType) type = type.returnType + if (type instanceof ptypes.FunctionPType) type = type.returnType const isGeneric = isGenericType(type) const isArc4Encoded = isArc4EncodedType(type) @@ -256,7 +237,7 @@ class ClassVisitor { private classDec: ts.ClassDeclaration, ) { const classType = helper.resolveType(classDec) - this.isArc4 = classType instanceof ContractClassPType && classType.isARC4 + this.isArc4 = classType instanceof ptypes.ContractClassPType && classType.isARC4 } public result(): ts.ClassDeclaration { @@ -267,7 +248,7 @@ class ClassVisitor { if (ts.isMethodDeclaration(node)) { if (this.classDec.name && this.isArc4) { const methodType = this.helper.resolveType(node) - if (methodType instanceof FunctionPType) { + if (methodType instanceof ptypes.FunctionPType) { this.helper.additionalStatements.push(nodeFactory.attachMetaData(this.classDec.name, node, methodType)) } } @@ -282,42 +263,50 @@ class ClassVisitor { } } -const isGenericType = (type: PType): boolean => +const isGenericType = (type: ptypes.PType): boolean => instanceOfAny( type, - ARC4StructType, - ARC4TupleType, - BoxMapPType, - BoxPType, - DynamicArrayType, - GlobalStateType, - LocalStateType, - StaticArrayType, - UFixedNxMType, - UintNType, + ptypes.ARC4StructType, + ptypes.ARC4TupleType, + ptypes.BoxMapPType, + ptypes.BoxPType, + ptypes.DynamicArrayType, + ptypes.GlobalStateType, + ptypes.LocalStateType, + ptypes.StaticArrayType, + ptypes.UFixedNxMType, + ptypes.UintNType, ) -const isArc4EncodedType = (type: PType): boolean => - instanceOfAny(type, ARC4StructType, ARC4TupleType, DynamicArrayType, StaticArrayType, UFixedNxMType, UintNType) || - type === ARC4StringType || - type === ARC4BooleanType - -const getGenericTypeInfo = (type: PType): TypeInfo => { +const isArc4EncodedType = (type: ptypes.PType): boolean => + instanceOfAny( + type, + ptypes.ARC4StructType, + ptypes.ARC4TupleType, + ptypes.DynamicArrayType, + ptypes.StaticArrayType, + ptypes.UFixedNxMType, + ptypes.UintNType, + ) || + type === ptypes.ARC4StringType || + type === ptypes.ARC4BooleanType + +const getGenericTypeInfo = (type: ptypes.PType): TypeInfo => { const genericArgs: TypeInfo[] | Record = [] - if (instanceOfAny(type, LocalStateType, GlobalStateType, BoxPType)) { + if (instanceOfAny(type, ptypes.LocalStateType, ptypes.GlobalStateType, ptypes.BoxPType)) { genericArgs.push(getGenericTypeInfo(type.contentType)) - } else if (type instanceof BoxMapPType) { + } else if (type instanceof ptypes.BoxMapPType) { genericArgs.push(getGenericTypeInfo(type.keyType)) genericArgs.push(getGenericTypeInfo(type.contentType)) - } else if (instanceOfAny(type, StaticArrayType, DynamicArrayType)) { + } else if (instanceOfAny(type, ptypes.StaticArrayType, ptypes.DynamicArrayType)) { genericArgs.push(getGenericTypeInfo(type.elementType)) - } else if (type instanceof UFixedNxMType) { + } else if (type instanceof ptypes.UFixedNxMType) { genericArgs.push({ name: type.n.toString() }) genericArgs.push({ name: type.m.toString() }) - } else if (type instanceof UintNType) { + } else if (type instanceof ptypes.UintNType) { genericArgs.push({ name: type.n.toString() }) - } else if (type instanceof ARC4StructType) { + } else if (type instanceof ptypes.ARC4StructType) { genericArgs.push( ...Object.fromEntries( Object.entries(type.fields) @@ -325,7 +314,7 @@ const getGenericTypeInfo = (type: PType): TypeInfo => { .filter((x) => !!x), ), ) - } else if (type instanceof ARC4TupleType) { + } else if (type instanceof ptypes.ARC4TupleType) { genericArgs.push(...type.items.map(getGenericTypeInfo)) } From 3adae24ecb87c74d76fa99af8f9b67a55c4e7e31 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 2 Dec 2024 16:11:42 +0800 Subject: [PATCH 61/85] refactor: add stub implementation for interpretAsArc4 method --- src/encoders.ts | 35 +- src/impl/base.ts | 15 +- src/impl/encoded-types.ts | 167 +- src/runtime-helpers.ts | 17 + src/test-transformer/helpers.ts | 2 + src/test-transformer/node-factory.ts | 13 +- src/test-transformer/visitors.ts | 45 +- src/util.ts | 6 +- tests/arc4/bool.spec.ts | 8 +- tests/arc4/byte.spec.ts | 16 +- tests/arc4/str.spec.ts | 10 +- tests/arc4/ufixednxm.spec.ts | 22 +- tests/arc4/uintn.spec.ts | 58 +- .../arc4-primitive-ops/contract.algo.ts | 44 +- .../Arc4PrimitiveOpsContract.approval.teal | 283 ++- .../data/Arc4PrimitiveOpsContract.arc32.json | 2 +- .../data/Arc4PrimitiveOpsContract.arc56.json | 1522 +++++++++++++++++ 17 files changed, 1944 insertions(+), 321 deletions(-) create mode 100644 tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc56.json diff --git a/src/encoders.ts b/src/encoders.ts index cfcf841..be9c12c 100644 --- a/src/encoders.ts +++ b/src/encoders.ts @@ -1,62 +1,61 @@ -import { biguint, BigUint, bytes, Bytes, internal, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import { biguint, BigUint, bytes, internal, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { OnCompleteAction } from '@algorandfoundation/algorand-typescript/arc4' import { AccountCls } from './impl/account' import { ApplicationCls } from './impl/application' import { AssetCls } from './impl/asset' +import { arc4Encoders, getArc4Encoder } from './impl/encoded-types' +import { DeliberateAny } from './typescript-helpers' +import { asBytes, asUint8Array } from './util' -export interface TypeInfo { +export type TypeInfo = { name: string genericArgs?: TypeInfo[] | Record } -type fromBytes = (val: Uint8Array, typeInfo: TypeInfo) => T +export type fromBytes = (val: Uint8Array | internal.primitives.StubBytesCompat, typeInfo: TypeInfo, prefix?: 'none' | 'log') => T const booleanFromBytes: fromBytes = (val) => { - return internal.encodingUtil.uint8ArrayToBigInt(val) > 0n + return internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val)) > 0n } const bigUintFromBytes: fromBytes = (val) => { - return BigUint(internal.encodingUtil.uint8ArrayToBigInt(val)) + return BigUint(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) } const bytesFromBytes: fromBytes = (val) => { - return Bytes(val) + return asBytes(val) } const stringFromBytes: fromBytes = (val) => { - return Bytes(val).toString() + return asBytes(val).toString() } const uint64FromBytes: fromBytes = (val) => { - return Uint64(internal.encodingUtil.uint8ArrayToBigInt(val)) + return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) } const onCompletionFromBytes: fromBytes = (val) => { - return Uint64(internal.encodingUtil.uint8ArrayToBigInt(val)) as OnCompleteAction + return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) as OnCompleteAction } const transactionTypeFromBytes: fromBytes = (val) => { - return Uint64(internal.encodingUtil.uint8ArrayToBigInt(val)) as TransactionType + return Uint64(internal.encodingUtil.uint8ArrayToBigInt(asUint8Array(val))) as TransactionType } -export const encoders = { +export const encoders: Record> = { account: AccountCls.fromBytes, application: ApplicationCls.fromBytes, asset: AssetCls.fromBytes, - 'bool(ean)?': booleanFromBytes, + boolean: booleanFromBytes, biguint: bigUintFromBytes, bytes: bytesFromBytes, string: stringFromBytes, uint64: uint64FromBytes, OnCompleteAction: onCompletionFromBytes, TransactionType: transactionTypeFromBytes, - // 'Tuple<*>': tupleFromBytes, + ...arc4Encoders, } export const getEncoder = (typeInfo: TypeInfo): fromBytes => { - const encoder = Object.entries(encoders).find(([k, _]) => new RegExp(`^${k}$`, 'i').test(typeInfo.name))?.[1] - if (!encoder) { - throw new Error(`No encoder found for type ${typeInfo.name}`) - } - return encoder as fromBytes + return getArc4Encoder(typeInfo, encoders) } diff --git a/src/impl/base.ts b/src/impl/base.ts index 0bf079f..45d4386 100644 --- a/src/impl/base.ts +++ b/src/impl/base.ts @@ -1,4 +1,4 @@ -import { Bytes, bytes, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { encodingUtil } from '@algorandfoundation/puya-ts' import type { TypeInfo } from '../encoders' @@ -14,8 +14,12 @@ export abstract class BytesBackedCls { // this.#typeInfo = typeInfo } - static fromBytes(this: { new (v: bytes, typeInfo?: TypeInfo): T }, value: Uint8Array, typeInfo?: TypeInfo) { - return new this(Bytes(value), typeInfo) + static fromBytes( + this: { new (v: bytes, typeInfo?: TypeInfo): T }, + value: internal.primitives.StubBytesCompat | Uint8Array, + typeInfo?: TypeInfo, + ) { + return new this(internal.primitives.BytesCls.fromCompat(value).asAlgoTs(), typeInfo) } } @@ -30,8 +34,9 @@ export abstract class Uint64BackedCls { this.#value = value } - static fromBytes(this: { new (v: uint64): T }, value: Uint8Array) { - const uint64Value = Uint64(encodingUtil.uint8ArrayToBigInt(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() + const uint64Value = Uint64(encodingUtil.uint8ArrayToBigInt(uint8ArrayValue)) return new this(uint64Value) } } diff --git a/src/impl/encoded-types.ts b/src/impl/encoded-types.ts index d47f58a..f4d579e 100644 --- a/src/impl/encoded-types.ts +++ b/src/impl/encoded-types.ts @@ -1,9 +1,9 @@ import { BigUintCompat, Bytes, bytes, internal, StringCompat, Uint64Compat } from '@algorandfoundation/algorand-typescript' -import { BitSize, Bool, Byte, Str, UFixedNxM, UintN } from '@algorandfoundation/algorand-typescript/arc4' +import { ARC4Encoded, BitSize, Bool, Byte, Str, UFixedNxM, UintN } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import assert from 'assert' import { ABI_RETURN_VALUE_LOG_PREFIX, BITS_IN_BYTE, UINT64_SIZE } from '../constants' -import { TypeInfo } from '../encoders' +import { fromBytes, TypeInfo } from '../encoders' import { DeliberateAny } from '../typescript-helpers' import { asBigUint, asBigUintCls, asBytesCls, asUint64, asUint8Array } from '../util' @@ -15,10 +15,10 @@ type CompatForArc4Int = N extends 8 | 16 | 32 | 64 ? Uint64Co export class UintNImpl extends UintN { private value: Uint8Array private bitSize: N - private typeInfo: TypeInfo + typeInfo: TypeInfo constructor(typeInfoString: string, v?: CompatForArc4Int) { - super(v) + super() this.typeInfo = JSON.parse(typeInfoString) this.bitSize = parseInt((this.typeInfo.genericArgs as TypeInfo[])![0].name, 10) as N @@ -40,32 +40,45 @@ export class UintNImpl extends UintN { return Bytes(this.value) } - static fromBytesImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): UintNImpl { - const result = new UintNImpl(typeInfo) - result.value = asUint8Array(value) - return result + 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}`) + } + return this.bytes.equals(other.bytes) } - static fromLogImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): UintNImpl { - const bytesValue = asBytesCls(value) - assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') - return UintNImpl.fromBytesImpl(typeInfo, bytesValue.slice(4)) + static fromBytesImpl( + value: internal.primitives.StubBytesCompat | Uint8Array, + typeInfo: string | TypeInfo, + prefix: 'none' | 'log' = 'none', + ): UintNImpl { + let bytesValue = asBytesCls(value) + if (prefix === 'log') { + assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') + bytesValue = bytesValue.slice(4) + } + const typeInfoString = typeof typeInfo === 'string' ? typeInfo : JSON.stringify(typeInfo) + const result = new UintNImpl(typeInfoString) + result.value = asUint8Array(bytesValue) + return result } } const regExpNxM = (maxPrecision: number) => new RegExp(`^\\d*\\.?\\d{0,${maxPrecision}}$`) const trimTrailingDecimalZeros = (v: string) => v.replace(/(\d+\.\d*?)0+$/, '$1').replace(/\.$/, '') +type uFixedNxMGenericArgs = { n: TypeInfo; m: TypeInfo } export class UFixedNxMImpl extends UFixedNxM { private value: Uint8Array - private typeInfo: TypeInfo private bitSize: N private precision: M + private typeInfo: TypeInfo constructor(typeInfoString: string, v: `${number}.${number}`) { super(v) this.typeInfo = JSON.parse(typeInfoString) - this.bitSize = parseInt((this.typeInfo.genericArgs as TypeInfo[])![0].name, 10) as N - this.precision = parseInt((this.typeInfo.genericArgs as TypeInfo[])![1].name, 10) as M + const genericArgs = this.typeInfo.genericArgs as uFixedNxMGenericArgs + this.bitSize = parseInt(genericArgs.n.name, 10) as N + this.precision = parseInt(genericArgs.m.name, 10) as M const trimmedValue = trimTrailingDecimalZeros(v) assert(regExpNxM(this.precision).test(trimmedValue), `expected positive decimal literal with max of ${this.precision} decimal places`) @@ -86,28 +99,34 @@ export class UFixedNxMImpl extends UFixedNx return Bytes(this.value) } - equals(other: UFixedNxM): boolean { - const otherImpl = other as UFixedNxMImpl - return this.bitSize === otherImpl.bitSize && this.precision === otherImpl.precision && this.value === otherImpl.value + 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}`) + } + return this.bytes.equals(other.bytes) } - static fromBytesImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): UFixedNxM { - const result = new UFixedNxMImpl(typeInfo, '0.0') - result.value = asUint8Array(value) + static fromBytesImpl( + value: internal.primitives.StubBytesCompat | Uint8Array, + typeInfo: string | TypeInfo, + prefix: 'none' | 'log' = 'none', + ): UFixedNxM { + let bytesValue = asBytesCls(value) + if (prefix === 'log') { + assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') + bytesValue = bytesValue.slice(4) + } + const typeInfoString = typeof typeInfo === 'string' ? typeInfo : JSON.stringify(typeInfo) + const result = new UFixedNxMImpl(typeInfoString, '0.0') + result.value = asUint8Array(bytesValue) return result } - - static fromLogImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): UFixedNxM { - const bytesValue = asBytesCls(value) - assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') - return UFixedNxMImpl.fromBytesImpl(typeInfo, bytesValue.slice(4)) - } } export class ByteImpl extends Byte { private value: UintNImpl<8> - constructor(typeInfoString: string, v: CompatForArc4Int<8>) { + constructor(typeInfoString: string, v?: CompatForArc4Int<8>) { super(v) this.value = new UintNImpl<8>(typeInfoString, v) } @@ -120,19 +139,30 @@ export class ByteImpl extends Byte { return this.value.bytes } - static fromBytesImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): Byte { - return UintNImpl.fromBytesImpl(typeInfo, value) as 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}`) + } + return this.bytes.equals(other.bytes) } - static fromLogImpl(typeInfo: string, value: internal.primitives.StubBytesCompat): Byte { - return UintNImpl.fromLogImpl(typeInfo, value) as Byte + static fromBytesImpl( + value: internal.primitives.StubBytesCompat | Uint8Array, + typeInfo: string | TypeInfo, + prefix: 'none' | 'log' = 'none', + ): ByteImpl { + const uintNValue = UintNImpl.fromBytesImpl(value, typeInfo, prefix) as UintNImpl<8> + const typeInfoString = typeof typeInfo === 'string' ? typeInfo : JSON.stringify(typeInfo) + const result = new ByteImpl(typeInfoString) + result.value = uintNValue + return result } } export class StrImpl extends Str { private value: Uint8Array - constructor(s?: StringCompat) { + constructor(_typeInfoString: string, s?: StringCompat) { super() const bytesValue = asBytesCls(s ?? '') const bytesLength = encodeLength(bytesValue.length.asNumber()) @@ -146,16 +176,27 @@ export class StrImpl extends Str { return Bytes(this.value) } - static fromBytesImpl(bytes: internal.primitives.StubBytesCompat): StrImpl { - const strValue = new StrImpl() - strValue.value = asUint8Array(bytes) - return strValue + equals(other: this): boolean { + if (!(other instanceof StrImpl)) { + throw new internal.errors.CodeError(`Expected expression of type ${Str}, got ${(other as object).constructor.name}`) + } + return this.bytes.equals(other.bytes) } - static fromLogImpl(value: internal.primitives.StubBytesCompat): StrImpl { - const bytesValue = asBytesCls(value) - assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') - return StrImpl.fromBytesImpl(bytesValue.slice(4)) + static fromBytesImpl( + value: internal.primitives.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') + bytesValue = bytesValue.slice(4) + } + const typeInfoString = typeof typeInfo === 'string' ? typeInfo : JSON.stringify(typeInfo) + const result = new StrImpl(typeInfoString) + result.value = asUint8Array(bytesValue) + return result } } const TRUE_BIGINT_VALUE = 128n @@ -164,7 +205,7 @@ const FALSE_BIGINT_VALUE = 0n export class BoolImpl extends Bool { private value: Uint8Array - constructor(v?: boolean) { + constructor(_typeInfoString: string, v?: boolean) { super(v) this.value = encodingUtil.bigIntToUint8Array(v ? TRUE_BIGINT_VALUE : FALSE_BIGINT_VALUE, 1) } @@ -177,15 +218,43 @@ export class BoolImpl extends Bool { return Bytes(this.value) } - static fromBytesImpl(value: internal.primitives.StubBytesCompat): BoolImpl { - const result = new BoolImpl() - result.value = asUint8Array(value) + static fromBytesImpl( + value: internal.primitives.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') + bytesValue = bytesValue.slice(4) + } + const typeInfoString = typeof typeInfo === 'string' ? typeInfo : JSON.stringify(typeInfo) + const result = new BoolImpl(typeInfoString) + result.value = asUint8Array(bytesValue) return result } +} + +export function interpretAsArc4Impl( + typeInfoString: string, + bytes: internal.primitives.StubBytesCompat, + prefix: 'none' | 'log' = 'none', +): T { + const typeInfo = JSON.parse(typeInfoString) + return getArc4Encoder(typeInfo)(bytes, typeInfo, prefix) +} - static fromLogImpl(value: internal.primitives.StubBytesCompat): BoolImpl { - const bytesValue = asBytesCls(value) - assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') - return BoolImpl.fromBytesImpl(bytesValue.slice(4)) +export const arc4Encoders: Record> = { + Bool: BoolImpl.fromBytesImpl, + Byte: ByteImpl.fromBytesImpl, + Str: StrImpl.fromBytesImpl, + 'UintN<.*>': UintNImpl.fromBytesImpl, + 'UFixedNxM<.*>': UFixedNxMImpl.fromBytesImpl, +} +export const getArc4Encoder = (typeInfo: TypeInfo, encoders?: Record>): fromBytes => { + const encoder = Object.entries(encoders ?? arc4Encoders).find(([k, _]) => new RegExp(`^${k}$`, 'i').test(typeInfo.name))?.[1] + if (!encoder) { + throw new Error(`No encoder found for type ${typeInfo.name}`) } + return encoder as fromBytes } diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 78f8803..5671a7e 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -1,4 +1,5 @@ import { internal } from '@algorandfoundation/algorand-typescript' +import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' import { MAX_UINT64 } from './constants' import type { TypeInfo } from './encoders' import { DeliberateAny } from './typescript-helpers' @@ -33,6 +34,9 @@ function tryGetBigInt(value: unknown): bigint | undefined { } export function binaryOp(left: unknown, right: unknown, op: BinaryOps) { + if (left instanceof ARC4Encoded && right instanceof ARC4Encoded) { + return arc4EncodedOp(left, right, op) + } if (left instanceof internal.primitives.BigUintCls || right instanceof internal.primitives.BigUintCls) { return bigUintBinaryOp(left, right, op) } @@ -67,6 +71,19 @@ export function unaryOp(operand: unknown, op: UnaryOps) { return defaultUnaryOp(operand, op) } +function arc4EncodedOp(left: ARC4Encoded, right: ARC4Encoded, op: BinaryOps): DeliberateAny { + const hasEqualsMethod = (x: ARC4Encoded) => Object.hasOwn(x, 'equals') && typeof (x as DeliberateAny).equals === 'function' + const compareEquality = (x: ARC4Encoded, y: ARC4Encoded) => + hasEqualsMethod(x) ? (x as DeliberateAny).equals(y) : (y as DeliberateAny).equals(x) + switch (op) { + case '===': + return compareEquality(left, right) + case '!==': + return !compareEquality(left, right) + default: + internal.errors.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() diff --git a/src/test-transformer/helpers.ts b/src/test-transformer/helpers.ts index d64bf69..51b1716 100644 --- a/src/test-transformer/helpers.ts +++ b/src/test-transformer/helpers.ts @@ -10,3 +10,5 @@ export const getPropertyNameAsString = (name: ts.PropertyName): ts.Identifier | } throw new TransformerError(`Node ${name.kind} cannot be converted to a static string`) } + +export const trimGenericTypeName = (typeName: string) => typeName.replace(/<.*>/, '') diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 88eed2f..f7f2577 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -2,7 +2,7 @@ import { ptypes } from '@algorandfoundation/puya-ts' import ts from 'typescript' import { TypeInfo } from '../encoders' import type { DeliberateAny } from '../typescript-helpers' -import { getPropertyNameAsString } from './helpers' +import { getPropertyNameAsString, trimGenericTypeName } from './helpers' const factory = ts.factory export const nodeFactory = { @@ -81,19 +81,20 @@ export const nodeFactory = { instantiateARC4EncodedType(node: ts.NewExpression, typeInfo?: TypeInfo) { const infoString = JSON.stringify(typeInfo) + const classIdentifier = node.expression.getText().replace('arc4.', '') return factory.createNewExpression( - factory.createIdentifier(`runtimeHelpers.${node.expression.getText().replace('arc4.', '')}Impl`), + factory.createIdentifier(`runtimeHelpers.${trimGenericTypeName(typeInfo?.name ?? classIdentifier)}Impl`), node.typeArguments, [infoString ? factory.createStringLiteral(infoString) : undefined, ...(node.arguments ?? [])].filter((arg) => !!arg), ) }, - callARC4EncodedStaticMethod(node: ts.CallExpression, typeInfo?: TypeInfo) { - const propertyAccessExpression = node.expression as ts.PropertyAccessExpression + callARC4EncodingUtil(node: ts.CallExpression, typeInfo?: TypeInfo) { + const identifierExpression = node.expression as ts.Identifier const infoString = JSON.stringify(typeInfo) const updatedPropertyAccessExpression = factory.createPropertyAccessExpression( - factory.createIdentifier(`runtimeHelpers.${propertyAccessExpression.expression.getText().replace('arc4.', '')}Impl`), - `${propertyAccessExpression.name.getText()}Impl`, + factory.createIdentifier('runtimeHelpers'), + `${identifierExpression.getText()}Impl`, ) return factory.createCallExpression( diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index 093f248..cba0798 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -93,12 +93,12 @@ class ExpressionVisitor { const isArc4Encoded = isArc4EncodedType(type) if (isGeneric || isArc4Encoded) { let updatedNode = node - const info = isGeneric ? getGenericTypeInfo(type) : undefined + const info = getGenericTypeInfo(type) if (isArc4EncodedType(type)) { if (ts.isNewExpression(updatedNode)) { updatedNode = nodeFactory.instantiateARC4EncodedType(updatedNode, info) - } else if (ts.isCallExpression(updatedNode) && isCallingARC4EncodedStaticMethod(updatedNode)) { - updatedNode = nodeFactory.callARC4EncodedStaticMethod(updatedNode, info) + } else if (ts.isCallExpression(updatedNode) && isCallingARC4EncodingUtils(updatedNode)) { + updatedNode = nodeFactory.callARC4EncodingUtil(updatedNode, info) } } return isGeneric @@ -194,7 +194,7 @@ class FunctionOrMethodVisitor { if (ts.isNewExpression(node)) { return new ExpressionVisitor(this.context, this.helper, node).result() } - if (ts.isCallExpression(node) && isCallingARC4EncodedStaticMethod(node)) { + if (ts.isCallExpression(node) && isCallingARC4EncodingUtils(node)) { return new ExpressionVisitor(this.context, this.helper, node).result() } @@ -292,7 +292,8 @@ const isArc4EncodedType = (type: ptypes.PType): boolean => type === ptypes.ARC4BooleanType const getGenericTypeInfo = (type: ptypes.PType): TypeInfo => { - const genericArgs: TypeInfo[] | Record = [] + let typeName = type?.name ?? type?.toString() ?? 'unknown' + let genericArgs: TypeInfo[] | Record = [] if (instanceOfAny(type, ptypes.LocalStateType, ptypes.GlobalStateType, ptypes.BoxPType)) { genericArgs.push(getGenericTypeInfo(type.contentType)) @@ -300,35 +301,37 @@ const getGenericTypeInfo = (type: ptypes.PType): TypeInfo => { genericArgs.push(getGenericTypeInfo(type.keyType)) genericArgs.push(getGenericTypeInfo(type.contentType)) } else if (instanceOfAny(type, ptypes.StaticArrayType, ptypes.DynamicArrayType)) { - genericArgs.push(getGenericTypeInfo(type.elementType)) + const entries = [] + entries.push(['elementType', getGenericTypeInfo(type.elementType)]) + if (instanceOfAny(type, ptypes.StaticArrayType)) { + entries.push(['size', { name: type.arraySize.toString() }]) + } + genericArgs = Object.fromEntries(entries) } else if (type instanceof ptypes.UFixedNxMType) { - genericArgs.push({ name: type.n.toString() }) - genericArgs.push({ name: type.m.toString() }) + genericArgs = { n: { name: type.n.toString() }, m: { name: type.m.toString() } } } else if (type instanceof ptypes.UintNType) { genericArgs.push({ name: type.n.toString() }) } else if (type instanceof ptypes.ARC4StructType) { - genericArgs.push( - ...Object.fromEntries( - Object.entries(type.fields) - .map(([key, value]) => [key, getGenericTypeInfo(value)]) - .filter((x) => !!x), - ), + typeName = 'Struct' + genericArgs = Object.fromEntries( + Object.entries(type.fields) + .map(([key, value]) => [key, getGenericTypeInfo(value)]) + .filter((x) => !!x), ) } else if (type instanceof ptypes.ARC4TupleType) { genericArgs.push(...type.items.map(getGenericTypeInfo)) } - const result: TypeInfo = { name: type?.name ?? type?.toString() ?? 'unknown' } + const result: TypeInfo = { name: typeName } if (genericArgs && (genericArgs.length || Object.keys(genericArgs).length)) { result.genericArgs = genericArgs } return result } -const isCallingARC4EncodedStaticMethod = (node: ts.CallExpression) => { - if (node.expression.kind !== ts.SyntaxKind.PropertyAccessExpression) return false - const propertyAccessExpression = node.expression as ts.PropertyAccessExpression - const staticMethodNames = ['fromBytes', 'fromLog'] - const propertyName = propertyAccessExpression.name.kind === ts.SyntaxKind.Identifier ? propertyAccessExpression.name.text : '' - return staticMethodNames.includes(propertyName) +const isCallingARC4EncodingUtils = (node: ts.CallExpression) => { + if (node.expression.kind !== ts.SyntaxKind.Identifier) return false + const identityExpression = node.expression as ts.Identifier + const utilMethods = ['interpretAsArc4', 'decodeArc4', 'encodeArc4'] + return utilMethods.includes(identityExpression.text) } diff --git a/src/util.ts b/src/util.ts index a5da4ca..c2296a5 100644 --- a/src/util.ts +++ b/src/util.ts @@ -35,15 +35,15 @@ export const asUint64Cls = (val: internal.primitives.StubUint64Compat) => intern export const asBigUintCls = (val: internal.primitives.StubBigUintCompat) => internal.primitives.BigUintCls.fromCompat(val) -export const asBytesCls = (val: internal.primitives.StubBytesCompat) => internal.primitives.BytesCls.fromCompat(val) +export const asBytesCls = (val: internal.primitives.StubBytesCompat | Uint8Array) => internal.primitives.BytesCls.fromCompat(val) export const asUint64 = (val: internal.primitives.StubUint64Compat) => asUint64Cls(val).asAlgoTs() export const asBigUint = (val: internal.primitives.StubBigUintCompat) => asBigUintCls(val).asAlgoTs() -export const asBytes = (val: internal.primitives.StubBytesCompat) => asBytesCls(val).asAlgoTs() +export const asBytes = (val: internal.primitives.StubBytesCompat | Uint8Array) => asBytesCls(val).asAlgoTs() -export const asUint8Array = (val: internal.primitives.StubBytesCompat) => asBytesCls(val).asUint8Array() +export const asUint8Array = (val: internal.primitives.StubBytesCompat | Uint8Array) => asBytesCls(val).asUint8Array() //TODO: handle arc4 types, bytes backed types export const toBytes = (val: unknown): bytes => { diff --git a/tests/arc4/bool.spec.ts b/tests/arc4/bool.spec.ts index 143c5c9..ca58ded 100644 --- a/tests/arc4/bool.spec.ts +++ b/tests/arc4/bool.spec.ts @@ -1,7 +1,7 @@ import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import { Bool } from '@algorandfoundation/algorand-typescript/arc4' +import { Bool, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' import { afterEach, describe, expect, test } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX } from '../../src/constants' import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' @@ -24,14 +24,14 @@ describe('arc4.Bool', async () => { 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 = Bool.fromBytes(Bytes(value)) + const result = interpretAsArc4(Bytes(value)) expect(result.native).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 = Bool.fromLog(Bytes(paddedValue)) + const result = interpretAsArc4(Bytes(paddedValue), 'log') expect(result.native).toEqual(avmResult) }) @@ -44,6 +44,6 @@ describe('arc4.Bool', async () => { await expect(() => getAvmResult({ appClient }, 'verify_bool_from_log', paddedValue)).rejects.toThrowError( new RegExp('(assert failed)|(extraction start \\d+ is beyond length)'), ) - expect(() => Bool.fromLog(Bytes(paddedValue))).toThrowError('ABI return prefix not found') + 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 c39aae6..b094826 100644 --- a/tests/arc4/byte.spec.ts +++ b/tests/arc4/byte.spec.ts @@ -1,7 +1,7 @@ import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import { Byte } from '@algorandfoundation/algorand-typescript/arc4' +import { Byte, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import { afterEach, describe, expect, it, test } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_UINT64 } from '../../src/constants' @@ -73,9 +73,9 @@ describe('arc4.Byte', async () => { const getStubResult = (a: Byte, b: Byte) => { switch (operator) { case '===': - return a.equals(b) + return a === b case '!==': - return !a.equals(b) + return a !== b case '<': return a.native < b.native case '<=': @@ -108,7 +108,7 @@ describe('arc4.Byte', async () => { encodingUtil.bigIntToUint8Array(2n ** 8n - 1n, 1), ])('create Byte from bytes', async (value) => { const avmResult = await getAvmResult({ appClient }, 'verify_byte_from_bytes', value) - const result = Byte.fromBytes(Bytes(value)) + const result = interpretAsArc4(Bytes(value)) expect(result.native).toEqual(avmResult) }) @@ -118,7 +118,7 @@ describe('arc4.Byte', async () => { async (value) => { await expect(getAvmResult({ appClient }, 'verify_byte_from_bytes', value)).rejects.toThrowError(invalidBytesLengthError) - const result = Byte.fromBytes(Bytes(value)) + const result = interpretAsArc4(Bytes(value)) expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }, ) @@ -131,7 +131,7 @@ describe('arc4.Byte', async () => { const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) const avmResult = await getAvmResult({ appClient }, 'verify_byte_from_log', logValue) - const result = Byte.fromLog(Bytes(logValue)) + const result = interpretAsArc4(Bytes(logValue), 'log') expect(avmResult).toEqual(expected) expect(result.native).toEqual(expected) }) @@ -144,7 +144,7 @@ describe('arc4.Byte', async () => { await expect(() => getAvmResult({ appClient }, 'verify_byte_from_log', logValue)).rejects.toThrowError( new RegExp('(assert failed)|(extraction start \\d+ is beyond length)'), ) - expect(() => Byte.fromLog(Bytes(logValue))).toThrowError('ABI return prefix not found') + expect(() => interpretAsArc4(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') }) test.each([ @@ -155,7 +155,7 @@ describe('arc4.Byte', async () => { 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 = Byte.fromLog(Bytes(logValue)) + const result = interpretAsArc4(Bytes(logValue), 'log') expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) }) diff --git a/tests/arc4/str.spec.ts b/tests/arc4/str.spec.ts index 325af58..99cbc1d 100644 --- a/tests/arc4/str.spec.ts +++ b/tests/arc4/str.spec.ts @@ -1,7 +1,7 @@ import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import { Str } from '@algorandfoundation/algorand-typescript/arc4' +import { interpretAsArc4, Str } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import { afterEach, describe, expect, test } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_LOG_SIZE } from '../../src/constants' @@ -48,7 +48,7 @@ describe('arc4.Str', async () => { const avmResult = await getAvmResult({ appClient }, 'verify_string_eq', asUint8Array(a), asUint8Array(b)) const aStr = new Str(a) const bStr = new Str(b) - const result = aStr.equals(bStr) + const result = aStr === bStr expect(result).toEqual(avmResult) }) @@ -69,7 +69,7 @@ describe('arc4.Str', async () => { ])('create Str from bytes', async (value) => { const paddedValue = new Uint8Array([...encodingUtil.bigIntToUint8Array(BigInt(value.length), 2), ...value]) const avmResult = await getAvmResult({ appClient }, 'verify_string_from_bytes', paddedValue) - const result = Str.fromBytes(Bytes(paddedValue)) + const result = interpretAsArc4(Bytes(paddedValue)) expect(result.native).toEqual(avmResult) }) @@ -84,7 +84,7 @@ describe('arc4.Str', async () => { ...value, ]) const avmResult = await getAvmResult({ appClient }, 'verify_string_from_log', paddedValue) - const result = Str.fromLog(Bytes(paddedValue)) + const result = interpretAsArc4(Bytes(paddedValue), 'log') expect(result.native).toEqual(avmResult) }) @@ -97,6 +97,6 @@ describe('arc4.Str', async () => { await expect(() => getAvmResult({ appClient }, 'verify_string_from_log', paddedValue)).rejects.toThrowError( new RegExp('(assert failed)|(extraction start \\d+ is beyond length)'), ) - expect(() => Str.fromLog(Bytes(paddedValue))).toThrowError('ABI return prefix not found') + expect(() => interpretAsArc4(Bytes(paddedValue), 'log')).toThrowError('ABI return prefix not found') }) }) diff --git a/tests/arc4/ufixednxm.spec.ts b/tests/arc4/ufixednxm.spec.ts index 42e37bd..cc9eb94 100644 --- a/tests/arc4/ufixednxm.spec.ts +++ b/tests/arc4/ufixednxm.spec.ts @@ -1,7 +1,7 @@ import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import { UFixedNxM } from '@algorandfoundation/algorand-typescript/arc4' +import { interpretAsArc4, UFixedNxM } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import { afterEach, describe, expect, test } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX } from '../../src/constants' @@ -62,7 +62,7 @@ describe('arc4.UFixedNxM', async () => { encodingUtil.bigIntToUint8Array(2n ** 32n - 1n), ])('create UFixedNxM<32,8> from bytes', async (value) => { const avmResult = await getAvmResult({ appClient }, 'verify_ufixednxm_from_bytes', value) - const result = UFixedNxM.fromBytes<32, 8>(Bytes(value)) + const result = interpretAsArc4>(Bytes(value)) expect(result.native).toEqual(avmResult) }) @@ -75,7 +75,7 @@ describe('arc4.UFixedNxM', async () => { ])('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)) - const result = UFixedNxM.fromBytes<32, 8>(Bytes(value)) + const result = interpretAsArc4>(Bytes(value)) expect(result.bytes).toEqual(value) }) @@ -88,7 +88,7 @@ describe('arc4.UFixedNxM', async () => { const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) const avmResult = await getAvmResult({ appClient }, 'verify_ufixednxm_from_log', logValue) - const result = UFixedNxM.fromLog<32, 8>(Bytes(logValue)) + const result = interpretAsArc4>(Bytes(logValue), 'log') expect(avmResult).toEqual(expected) expect(result.native).toEqual(expected) }) @@ -99,7 +99,7 @@ describe('arc4.UFixedNxM', async () => { ])('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(() => UFixedNxM.fromLog<32, 8>(Bytes(logValue))).toThrowError('ABI return prefix not found') + expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') }) test.each([ @@ -111,7 +111,7 @@ describe('arc4.UFixedNxM', async () => { 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 = UFixedNxM.fromLog<32, 8>(Bytes(logValue)) + const result = interpretAsArc4>(Bytes(logValue), 'log') expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) @@ -122,7 +122,7 @@ describe('arc4.UFixedNxM', async () => { encodingUtil.bigIntToUint8Array(2n ** 256n - 1n), ])('create UFixedNxM<256,16> from bytes', async (value) => { const avmResult = await getAvmResult({ appClient }, 'verify_bigufixednxm_from_bytes', value) - const result = UFixedNxM.fromBytes<256, 16>(Bytes(value)) + const result = interpretAsArc4>(Bytes(value)) expect(result.native).toEqual(avmResult) }) @@ -135,7 +135,7 @@ describe('arc4.UFixedNxM', async () => { ])('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)) - const result = UFixedNxM.fromBytes<256, 16>(Bytes(value)) + const result = interpretAsArc4>(Bytes(value)) expect(result.bytes).toEqual(value) }) @@ -148,7 +148,7 @@ describe('arc4.UFixedNxM', async () => { const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) const avmResult = await getAvmResult({ appClient }, 'verify_bigufixednxm_from_log', logValue) - const result = UFixedNxM.fromLog<256, 16>(Bytes(logValue)) + const result = interpretAsArc4>(Bytes(logValue), 'log') expect(avmResult).toEqual(expected) expect(result.native).toEqual(expected) }) @@ -159,7 +159,7 @@ describe('arc4.UFixedNxM', async () => { ])('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(() => UFixedNxM.fromLog<256, 16>(Bytes(logValue))).toThrowError('ABI return prefix not found') + expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') }) test.each([ @@ -173,7 +173,7 @@ describe('arc4.UFixedNxM', async () => { invalidBytesLengthError(256), ) - const result = UFixedNxM.fromLog<256, 16>(Bytes(logValue)) + 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 d18b7da..b3e8c77 100644 --- a/tests/arc4/uintn.spec.ts +++ b/tests/arc4/uintn.spec.ts @@ -1,11 +1,10 @@ import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import { UintN } from '@algorandfoundation/algorand-typescript/arc4' +import { BitSize, 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 { ABI_RETURN_VALUE_LOG_PREFIX, MAX_UINT512, MAX_UINT64 } from '../../src/constants' -import { DeliberateAny } from '../../src/typescript-helpers' import { asBigUintCls } from '../../src/util' import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' @@ -24,14 +23,14 @@ describe('arc4.UintN', async () => { const bytesValue = asBigUintCls(value).toBytes() await expect(getAvmResult({ appClient }, 'verify_uintn_init', asUint8Array(bytesValue))).rejects.toThrowError() - expect(() => new UintN<32>(value)).toThrowError(`expected value <= ${2 ** 32 - 1}`) + 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() await expect(getAvmResult({ appClient }, 'verify_biguintn_init', asUint8Array(bytesValue))).rejects.toThrowError() - expect(() => new UintN<256>(value)).toThrowError(`expected value <= ${2 ** 256 - 1}`) + expect(() => new UintN256(value)).toThrowError(`expected value <= ${2 ** 256 - 1}`) }) test.each([ @@ -42,7 +41,7 @@ describe('arc4.UintN', async () => { const bytesValue = asBigUintCls(value).toBytes() const avmResult = await getAvmResult({ appClient }, 'verify_uintn_init', asUint8Array(bytesValue)) - const result = new UintN<32>(value) + const result = new UintN32(value) expect(result.native).toEqual(BigInt(expected)) expect(avmResult).toEqual(BigInt(expected)) @@ -58,16 +57,16 @@ describe('arc4.UintN', async () => { const bytesValue = asBigUintCls(value).toBytes() const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_init', asUint8Array(bytesValue)) - const result = new UintN<256>(value) + const result = new UintN256(value) expect(result.native).toEqual(BigInt(expected)) expect(avmResult).toEqual(BigInt(expected)) }) test.each([0, 1, 255])('should be able to get bytes representation of %s', async (value) => { - expect(new UintN<8>(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 1)) - expect(new UintN<16>(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 2)) - expect(new UintN<64>(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 8)) + 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)) expect(new UintN<512>(value).bytes).toEqual(encodingUtil.bigIntToUint8Array(BigInt(value), 64)) }) @@ -100,17 +99,14 @@ describe('arc4.UintN', async () => { [MAX_UINT64, MAX_UINT64], [65535, 4294967295], [4294967295, MAX_UINT64], - [MAX_UINT64, MAX_UINT512], - [0, MAX_UINT512], - [1, MAX_UINT512], [MAX_UINT512, MAX_UINT512], ])(`${operator}`, async (a, b) => { - const getStubResult = (a: UintN, b: UintN) => { + const getStubResult = (a: UintN, b: UintN) => { switch (operator) { case '===': - return a.equals(b) + return a === b case '!==': - return !a.equals(b) + return a !== b case '<': return a.native < b.native case '<=': @@ -144,6 +140,17 @@ describe('arc4.UintN', async () => { }) }) + test.each([ + [MAX_UINT64, MAX_UINT512], + [0, MAX_UINT512], + [1, MAX_UINT512], + ])('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([ encodingUtil.bigIntToUint8Array(0n, 4), encodingUtil.bigIntToUint8Array(255n, 4), @@ -152,7 +159,8 @@ describe('arc4.UintN', async () => { encodingUtil.bigIntToUint8Array(2n ** 32n - 1n), ])('create UintN<32> from bytes', async (value) => { const avmResult = await getAvmResult({ appClient }, 'verify_uintn_from_bytes', value) - const result = UintN.fromBytes<32>(Bytes(value)) + + const result = interpretAsArc4(Bytes(value)) expect(result.native).toEqual(avmResult) }) @@ -165,7 +173,7 @@ describe('arc4.UintN', async () => { ])('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)) - const result = UintN.fromBytes<32>(Bytes(value)) + const result = interpretAsArc4(Bytes(value)) expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) @@ -176,7 +184,7 @@ describe('arc4.UintN', async () => { encodingUtil.bigIntToUint8Array(2n ** 256n - 1n), ])('create UintN<256> from bytes', async (value) => { const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_from_bytes', value) - const result = UintN.fromBytes<256>(Bytes(value)) + const result = interpretAsArc4(Bytes(value)) expect(result.native).toEqual(avmResult) }) @@ -189,7 +197,7 @@ describe('arc4.UintN', async () => { ])('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)) - const result = UintN.fromBytes<256>(Bytes(value)) + const result = interpretAsArc4(Bytes(value)) expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) @@ -202,7 +210,7 @@ describe('arc4.UintN', async () => { const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) const avmResult = await getAvmResult({ appClient }, 'verify_uintn_from_log', logValue) - const result = UintN.fromLog<32>(Bytes(logValue)) + const result = interpretAsArc4>(Bytes(logValue), 'log') expect(avmResult).toEqual(expected) expect(result.native).toEqual(expected) }) @@ -213,7 +221,7 @@ describe('arc4.UintN', async () => { ])('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(() => UintN.fromLog<32>(Bytes(logValue))).toThrowError('ABI return prefix not found') + expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') }) test.each([ @@ -225,7 +233,7 @@ describe('arc4.UintN', async () => { 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 = UintN.fromLog<32>(Bytes(logValue)) + const result = interpretAsArc4>(Bytes(logValue), 'log') expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) @@ -238,7 +246,7 @@ describe('arc4.UintN', async () => { const logValue = asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(value))) const avmResult = await getAvmResult({ appClient }, 'verify_biguintn_from_log', logValue) - const result = UintN.fromLog<256>(Bytes(logValue)) + const result = interpretAsArc4>(Bytes(logValue), 'log') expect(avmResult).toEqual(expected) expect(result.native).toEqual(expected) }) @@ -249,7 +257,7 @@ describe('arc4.UintN', async () => { ])('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(() => UintN.fromLog<256>(Bytes(logValue))).toThrowError('ABI return prefix not found') + expect(() => interpretAsArc4>(Bytes(logValue), 'log')).toThrowError('ABI return prefix not found') }) test.each([ @@ -261,7 +269,7 @@ describe('arc4.UintN', async () => { 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 = UintN.fromLog<256>(Bytes(logValue)) + const result = interpretAsArc4>(Bytes(logValue), 'log') expect(result.native).toEqual(encodingUtil.uint8ArrayToBigInt(value)) }) }) diff --git a/tests/artifacts/arc4-primitive-ops/contract.algo.ts b/tests/artifacts/arc4-primitive-ops/contract.algo.ts index 42a7a93..345a365 100644 --- a/tests/artifacts/arc4-primitive-ops/contract.algo.ts +++ b/tests/artifacts/arc4-primitive-ops/contract.algo.ts @@ -1,5 +1,5 @@ import { arc4, BigUint, bytes } from '@algorandfoundation/algorand-typescript' -import { Bool, Byte, Contract, Str, UFixedNxM, UintN } from '@algorandfoundation/algorand-typescript/arc4' +import { Bool, Byte, Contract, interpretAsArc4, Str, UFixedNxM, UintN } from '@algorandfoundation/algorand-typescript/arc4' export class Arc4PrimitiveOpsContract extends Contract { @arc4.abimethod() @@ -8,7 +8,7 @@ export class Arc4PrimitiveOpsContract extends Contract { const bBiguint = BigUint(b) const aUintN = new UintN<64>(aBiguint) const bUintN = new UintN<64>(bBiguint) - return aUintN.equals(bUintN) + return aUintN === bUintN } @arc4.abimethod() public verify_biguintn_uintn_eq(a: bytes, b: bytes): boolean { @@ -32,7 +32,7 @@ export class Arc4PrimitiveOpsContract extends Contract { const bBiguint = BigUint(b) const aUintN = new UintN<512>(aBiguint) const bUintN = new UintN<512>(bBiguint) - return aUintN.equals(bUintN) + return aUintN === bUintN } @arc4.abimethod() public verify_byte_byte_eq(a: bytes, b: bytes): boolean { @@ -40,7 +40,7 @@ export class Arc4PrimitiveOpsContract extends Contract { const bBiguint = BigUint(b) const aByte = new Byte(aBiguint) const bByte = new Byte(bBiguint) - return aByte.equals(bByte) + return aByte === bByte } @arc4.abimethod() public verify_uintn_uintn_ne(a: bytes, b: bytes): boolean { @@ -48,7 +48,7 @@ export class Arc4PrimitiveOpsContract extends Contract { const bBiguint = BigUint(b) const aUintN = new UintN<64>(aBiguint) const bUintN = new UintN<64>(bBiguint) - return !aUintN.equals(bUintN) + return aUintN !== bUintN } @arc4.abimethod() public verify_biguintn_uintn_ne(a: bytes, b: bytes): boolean { @@ -72,7 +72,7 @@ export class Arc4PrimitiveOpsContract extends Contract { const bBiguint = BigUint(b) const aUintN = new UintN<512>(aBiguint) const bUintN = new UintN<512>(bBiguint) - return !aUintN.equals(bUintN) + return aUintN !== bUintN } @arc4.abimethod() public verify_byte_byte_ne(a: bytes, b: bytes): boolean { @@ -80,7 +80,7 @@ export class Arc4PrimitiveOpsContract extends Contract { const bBiguint = BigUint(b) const aByte = new Byte(aBiguint) const bByte = new Byte(bBiguint) - return !aByte.equals(bByte) + return aByte !== bByte } @arc4.abimethod() public verify_uintn_uintn_lt(a: bytes, b: bytes): boolean { @@ -259,27 +259,27 @@ export class Arc4PrimitiveOpsContract extends Contract { } @arc4.abimethod() public verify_uintn_from_bytes(a: bytes): UintN<32> { - return UintN.fromBytes<32>(a) + return interpretAsArc4>(a) } @arc4.abimethod() public verify_biguintn_from_bytes(a: bytes): UintN<256> { - return UintN.fromBytes<256>(a) + return interpretAsArc4>(a) } @arc4.abimethod() public verify_byte_from_bytes(a: bytes): Byte { - return Byte.fromBytes(a) + return interpretAsArc4(a) } @arc4.abimethod() public verify_uintn_from_log(a: bytes): UintN<32> { - return UintN.fromLog<32>(a) + return interpretAsArc4>(a, 'log') } @arc4.abimethod() public verify_biguintn_from_log(a: bytes): UintN<256> { - return UintN.fromLog<256>(a) + return interpretAsArc4>(a, 'log') } @arc4.abimethod() public verify_byte_from_log(a: bytes): Byte { - return Byte.fromLog(a) + return interpretAsArc4(a, 'log') } @arc4.abimethod() public verify_ufixednxm_bytes(a: UFixedNxM<32, 8>): bytes { @@ -291,19 +291,19 @@ export class Arc4PrimitiveOpsContract extends Contract { } @arc4.abimethod() public verify_ufixednxm_from_bytes(a: bytes): UFixedNxM<32, 8> { - return UFixedNxM.fromBytes<32, 8>(a) + return interpretAsArc4>(a) } @arc4.abimethod() public verify_bigufixednxm_from_bytes(a: bytes): UFixedNxM<256, 16> { - return UFixedNxM.fromBytes<256, 16>(a) + return interpretAsArc4>(a) } @arc4.abimethod() public verify_ufixednxm_from_log(a: bytes): UFixedNxM<32, 8> { - return UFixedNxM.fromLog<32, 8>(a) + return interpretAsArc4>(a, 'log') } @arc4.abimethod() public verify_bigufixednxm_from_log(a: bytes): UFixedNxM<256, 16> { - return UFixedNxM.fromLog<256, 16>(a) + return interpretAsArc4>(a, 'log') } @arc4.abimethod() public verify_string_init(a: string): Str { @@ -317,7 +317,7 @@ export class Arc4PrimitiveOpsContract extends Contract { } @arc4.abimethod() public verify_string_eq(a: Str, b: Str): boolean { - return a.equals(b) + return a === b } @arc4.abimethod() public verify_string_bytes(a: string): bytes { @@ -326,11 +326,11 @@ export class Arc4PrimitiveOpsContract extends Contract { } @arc4.abimethod() public verify_string_from_bytes(a: bytes): Str { - return Str.fromBytes(a) + return interpretAsArc4(a) } @arc4.abimethod() public verify_string_from_log(a: bytes): Str { - return Str.fromLog(a) + return interpretAsArc4(a, 'log') } @arc4.abimethod() public verify_bool_bytes(a: Bool): bytes { @@ -338,10 +338,10 @@ export class Arc4PrimitiveOpsContract extends Contract { } @arc4.abimethod() public verify_bool_from_bytes(a: bytes): Bool { - return Bool.fromBytes(a) + return interpretAsArc4(a) } @arc4.abimethod() public verify_bool_from_log(a: bytes): Bool { - return Bool.fromLog(a) + return interpretAsArc4(a, 'log') } } diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal index 26a7070..b4b93f4 100644 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal @@ -25,9 +25,9 @@ __puya_arc4_router___verify_uintn_uintn_eq_route@2: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -53,9 +53,9 @@ __puya_arc4_router___verify_biguintn_uintn_eq_route@3: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -81,9 +81,9 @@ __puya_arc4_router___verify_uintn_biguintn_eq_route@4: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -109,9 +109,9 @@ __puya_arc4_router___verify_biguintn_biguintn_eq_route@5: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -137,9 +137,9 @@ __puya_arc4_router___verify_byte_byte_eq_route@6: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -165,9 +165,9 @@ __puya_arc4_router___verify_uintn_uintn_ne_route@7: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -193,9 +193,9 @@ __puya_arc4_router___verify_biguintn_uintn_ne_route@8: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -221,9 +221,9 @@ __puya_arc4_router___verify_uintn_biguintn_ne_route@9: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -249,9 +249,9 @@ __puya_arc4_router___verify_biguintn_biguintn_ne_route@10: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -277,9 +277,9 @@ __puya_arc4_router___verify_byte_byte_ne_route@11: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -305,9 +305,9 @@ __puya_arc4_router___verify_uintn_uintn_lt_route@12: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -333,9 +333,9 @@ __puya_arc4_router___verify_biguintn_uintn_lt_route@13: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -361,9 +361,9 @@ __puya_arc4_router___verify_uintn_biguintn_lt_route@14: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -389,9 +389,9 @@ __puya_arc4_router___verify_biguintn_biguintn_lt_route@15: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -417,9 +417,9 @@ __puya_arc4_router___verify_byte_byte_lt_route@16: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -445,9 +445,9 @@ __puya_arc4_router___verify_uintn_uintn_le_route@17: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -473,9 +473,9 @@ __puya_arc4_router___verify_biguintn_uintn_le_route@18: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -501,9 +501,9 @@ __puya_arc4_router___verify_uintn_biguintn_le_route@19: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -529,9 +529,9 @@ __puya_arc4_router___verify_biguintn_biguintn_le_route@20: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -557,9 +557,9 @@ __puya_arc4_router___verify_byte_byte_le_route@21: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -585,9 +585,9 @@ __puya_arc4_router___verify_uintn_uintn_gt_route@22: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -613,9 +613,9 @@ __puya_arc4_router___verify_biguintn_uintn_gt_route@23: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -641,9 +641,9 @@ __puya_arc4_router___verify_uintn_biguintn_gt_route@24: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -669,9 +669,9 @@ __puya_arc4_router___verify_biguintn_biguintn_gt_route@25: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -697,9 +697,9 @@ __puya_arc4_router___verify_byte_byte_gt_route@26: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -725,9 +725,9 @@ __puya_arc4_router___verify_uintn_uintn_ge_route@27: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -753,9 +753,9 @@ __puya_arc4_router___verify_biguintn_uintn_ge_route@28: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -781,9 +781,9 @@ __puya_arc4_router___verify_uintn_biguintn_ge_route@29: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -809,9 +809,9 @@ __puya_arc4_router___verify_biguintn_biguintn_ge_route@30: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -837,9 +837,9 @@ __puya_arc4_router___verify_byte_byte_ge_route@31: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -865,9 +865,9 @@ __puya_arc4_router___verify_uintn_init_route@32: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -887,9 +887,9 @@ __puya_arc4_router___verify_biguintn_init_route@33: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -909,9 +909,9 @@ __puya_arc4_router___verify_byte_init_route@34: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -931,9 +931,9 @@ __puya_arc4_router___verify_uintn_from_bytes_route@35: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -953,9 +953,9 @@ __puya_arc4_router___verify_biguintn_from_bytes_route@36: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -975,9 +975,9 @@ __puya_arc4_router___verify_byte_from_bytes_route@37: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -997,9 +997,9 @@ __puya_arc4_router___verify_uintn_from_log_route@38: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1019,9 +1019,9 @@ __puya_arc4_router___verify_biguintn_from_log_route@39: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1041,9 +1041,9 @@ __puya_arc4_router___verify_byte_from_log_route@40: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1063,9 +1063,9 @@ __puya_arc4_router___verify_ufixednxm_bytes_route@41: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1090,9 +1090,9 @@ __puya_arc4_router___verify_bigufixednxm_bytes_route@42: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1117,9 +1117,9 @@ __puya_arc4_router___verify_ufixednxm_from_bytes_route@43: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1139,9 +1139,9 @@ __puya_arc4_router___verify_bigufixednxm_from_bytes_route@44: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1161,9 +1161,9 @@ __puya_arc4_router___verify_ufixednxm_from_log_route@45: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1183,9 +1183,9 @@ __puya_arc4_router___verify_bigufixednxm_from_log_route@46: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1205,9 +1205,9 @@ __puya_arc4_router___verify_string_init_route@47: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1227,9 +1227,9 @@ __puya_arc4_router___verify_string_add_route@48: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1249,9 +1249,9 @@ __puya_arc4_router___verify_string_eq_route@49: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1275,9 +1275,9 @@ __puya_arc4_router___verify_string_bytes_route@50: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1303,9 +1303,9 @@ __puya_arc4_router___verify_string_from_bytes_route@51: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1325,9 +1325,9 @@ __puya_arc4_router___verify_string_from_log_route@52: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1347,9 +1347,9 @@ __puya_arc4_router___verify_bool_bytes_route@53: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1374,9 +1374,9 @@ __puya_arc4_router___verify_bool_from_bytes_route@54: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1396,9 +1396,9 @@ __puya_arc4_router___verify_bool_from_log_route@55: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 @@ -1420,7 +1420,7 @@ __puya_arc4_router___bare_routing@58: bnz __puya_arc4_router___after_if_else@62 txn ApplicationID ! - assert // is creating + assert // can only call when creating intc_0 // 1 retsub @@ -1460,7 +1460,7 @@ verify_uintn_uintn_eq: uncover 2 b| // tests/artifacts/arc4-primitive-ops/contract.algo.ts:11 - // return aUintN.equals(bUintN) + // return aUintN === bUintN == retsub @@ -1562,7 +1562,7 @@ verify_biguintn_biguintn_eq: uncover 2 b| // tests/artifacts/arc4-primitive-ops/contract.algo.ts:35 - // return aUintN.equals(bUintN) + // return aUintN === bUintN == retsub @@ -1596,7 +1596,7 @@ verify_byte_byte_eq: uncover 2 b| // tests/artifacts/arc4-primitive-ops/contract.algo.ts:43 - // return aByte.equals(bByte) + // return aByte === bByte == retsub @@ -1630,9 +1630,8 @@ verify_uintn_uintn_ne: uncover 2 b| // tests/artifacts/arc4-primitive-ops/contract.algo.ts:51 - // return !aUintN.equals(bUintN) - == - ! + // return aUintN !== bUintN + != retsub @@ -1735,9 +1734,8 @@ verify_biguintn_biguintn_ne: uncover 2 b| // tests/artifacts/arc4-primitive-ops/contract.algo.ts:75 - // return !aUintN.equals(bUintN) - == - ! + // return aUintN !== bUintN + != retsub @@ -1770,9 +1768,8 @@ verify_byte_byte_ne: uncover 2 b| // tests/artifacts/arc4-primitive-ops/contract.algo.ts:83 - // return !aByte.equals(bByte) - == - ! + // return aByte !== bByte + != retsub @@ -2575,7 +2572,7 @@ verify_uintn_from_bytes: // public verify_uintn_from_bytes(a: bytes): UintN<32> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:262 - // return UintN.fromBytes<32>(a) + // return interpretAsArc4>(a) frame_dig -1 retsub @@ -2587,7 +2584,7 @@ verify_biguintn_from_bytes: // public verify_biguintn_from_bytes(a: bytes): UintN<256> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:266 - // return UintN.fromBytes<256>(a) + // return interpretAsArc4>(a) frame_dig -1 retsub @@ -2599,7 +2596,7 @@ verify_byte_from_bytes: // public verify_byte_from_bytes(a: bytes): Byte { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:270 - // return Byte.fromBytes(a) + // return interpretAsArc4(a) frame_dig -1 retsub @@ -2611,14 +2608,14 @@ verify_uintn_from_log: // public verify_uintn_from_log(a: bytes): UintN<32> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:274 - // return UintN.fromLog<32>(a) + // return interpretAsArc4>(a, 'log') frame_dig -1 extract 4 0 frame_dig -1 extract 0 4 bytec_0 // 0x151f7c75 == - assert // ARC4 prefix is valid + assert // Bytes has valid prefix retsub @@ -2629,14 +2626,14 @@ verify_biguintn_from_log: // public verify_biguintn_from_log(a: bytes): UintN<256> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:278 - // return UintN.fromLog<256>(a) + // return interpretAsArc4>(a, 'log') frame_dig -1 extract 4 0 frame_dig -1 extract 0 4 bytec_0 // 0x151f7c75 == - assert // ARC4 prefix is valid + assert // Bytes has valid prefix retsub @@ -2647,14 +2644,14 @@ verify_byte_from_log: // public verify_byte_from_log(a: bytes): Byte { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:282 - // return Byte.fromLog(a) + // return interpretAsArc4(a, 'log') frame_dig -1 extract 4 0 frame_dig -1 extract 0 4 bytec_0 // 0x151f7c75 == - assert // ARC4 prefix is valid + assert // Bytes has valid prefix retsub @@ -2689,7 +2686,7 @@ verify_ufixednxm_from_bytes: // public verify_ufixednxm_from_bytes(a: bytes): UFixedNxM<32, 8> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:294 - // return UFixedNxM.fromBytes<32, 8>(a) + // return interpretAsArc4>(a) frame_dig -1 retsub @@ -2701,7 +2698,7 @@ verify_bigufixednxm_from_bytes: // public verify_bigufixednxm_from_bytes(a: bytes): UFixedNxM<256, 16> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:298 - // return UFixedNxM.fromBytes<256, 16>(a) + // return interpretAsArc4>(a) frame_dig -1 retsub @@ -2713,14 +2710,14 @@ verify_ufixednxm_from_log: // public verify_ufixednxm_from_log(a: bytes): UFixedNxM<32, 8> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:302 - // return UFixedNxM.fromLog<32, 8>(a) + // return interpretAsArc4>(a, 'log') frame_dig -1 extract 4 0 frame_dig -1 extract 0 4 bytec_0 // 0x151f7c75 == - assert // ARC4 prefix is valid + assert // Bytes has valid prefix retsub @@ -2731,14 +2728,14 @@ verify_bigufixednxm_from_log: // public verify_bigufixednxm_from_log(a: bytes): UFixedNxM<256, 16> { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:306 - // return UFixedNxM.fromLog<256, 16>(a) + // return interpretAsArc4>(a, 'log') frame_dig -1 extract 4 0 frame_dig -1 extract 0 4 bytec_0 // 0x151f7c75 == - assert // ARC4 prefix is valid + assert // Bytes has valid prefix retsub @@ -2795,7 +2792,7 @@ verify_string_eq: // public verify_string_eq(a: Str, b: Str): boolean { proto 2 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:320 - // return a.equals(b) + // return a === b frame_dig -2 frame_dig -1 == @@ -2828,7 +2825,7 @@ verify_string_from_bytes: // public verify_string_from_bytes(a: bytes): Str { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:329 - // return Str.fromBytes(a) + // return interpretAsArc4(a) frame_dig -1 retsub @@ -2840,14 +2837,14 @@ verify_string_from_log: // public verify_string_from_log(a: bytes): Str { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:333 - // return Str.fromLog(a) + // return interpretAsArc4(a, 'log') frame_dig -1 extract 4 0 frame_dig -1 extract 0 4 bytec_0 // 0x151f7c75 == - assert // ARC4 prefix is valid + assert // Bytes has valid prefix retsub @@ -2870,7 +2867,7 @@ verify_bool_from_bytes: // public verify_bool_from_bytes(a: bytes): Bool { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:341 - // return Bool.fromBytes(a) + // return interpretAsArc4(a) frame_dig -1 retsub @@ -2882,12 +2879,12 @@ verify_bool_from_log: // public verify_bool_from_log(a: bytes): Bool { proto 1 1 // tests/artifacts/arc4-primitive-ops/contract.algo.ts:345 - // return Bool.fromLog(a) + // return interpretAsArc4(a, 'log') frame_dig -1 extract 4 0 frame_dig -1 extract 0 4 bytec_0 // 0x151f7c75 == - assert // ARC4 prefix is valid + assert // Bytes has valid prefix retsub diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json index 11a0c0c..7d20805 100644 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json @@ -272,7 +272,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSA4IDY0IDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NSAweDAwCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OAogICAgcHVzaGJ5dGVzcyAweDk2ZjE0MTE2IDB4ZWQ2NjYwOTYgMHgyY2EwMzUyYiAweDg1OTA3ZDQwIDB4NGViMmFmNGEgMHgyY2JlYzQ1YiAweDA3NjY2ZmQ5IDB4MzcwYmFiZDMgMHgyYjZiM2VmMCAweDI3ZTIxYTk4IDB4MzM5ZGE5N2MgMHg3ODk4ZWQ5NyAweDFmMTMwY2VjIDB4Yzc0ODY2NGUgMHhhMmJhYzE0YiAweDdhNDYwY2IxIDB4ZGNhYjFmMDEgMHg5N2Q5MDY0ZCAweGNlMDZjMmEwIDB4N2MxMWUzNzUgMHhkY2RiY2VlMCAweDc3YTRiNjhkIDB4NGY1NDA2MjYgMHgwOTVhZWQ0MSAweGRmNzhjZGM2IDB4ZTNiN2U5MTggMHg1NTMzNzAwOCAweDliYjFjZDY2IDB4ODE0ODRkOWQgMHg3OWU5Y2IwMyAweDlhMDNkZjEwIDB4ZDNmMGU0NGIgMHg2NzNkYjJiZCAweDk4MmRiMjMzIDB4YWZmYmRmMGUgMHg4ZTRhMzBmNyAweDI4OGFmNzZlIDB4OGJkODRhMDQgMHhmY2Q1NWUxZiAweDBmMTU3NGZlIDB4YjJjYjEzYmUgMHhkMDU5ZWVhNyAweDRjYzRjMTU3IDB4M2QxN2FjNmUgMHhmN2YzZDVmYyAweGY4YzhmOGQ1IDB4NDNmNzE2MmEgMHg0MmUwOTA3NSAweGQ5NTZmNTc1IDB4NmMwMTYwZGYgMHhhODkwMTUwYiAweDBiMmY0YzNmIDB4OWRiOWQzMjcgMHhlNGQ5NTBhMSAvLyBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfZXEoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9sdChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfbGUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2d0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9nZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9pbml0KGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9pbml0KGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9pbml0KGJ5dGVbXSlieXRlIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDMyIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhieXRlW10pYnl0ZSIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9sb2coYnl0ZVtdKWJ5dGUiLCBtZXRob2QgInZlcmlmeV91Zml4ZWRueG1fYnl0ZXModWZpeGVkMzJ4OClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXModWZpeGVkMjU2eDE2KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGJ5dGVbXSl1Zml4ZWQzMng4IiwgbWV0aG9kICJ2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMoYnl0ZVtdKXVmaXhlZDI1NngxNiIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMzJ4OCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMjU2eDE2IiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2luaXQoc3RyaW5nKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19hZGQoc3RyaW5nLHN0cmluZylzdHJpbmciLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZXEoc3RyaW5nLHN0cmluZylib29sIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2J5dGVzKHN0cmluZylieXRlW10iLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhieXRlW10pc3RyaW5nIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nKGJ5dGVbXSlzdHJpbmciLCBtZXRob2QgInZlcmlmeV9ib29sX2J5dGVzKGJvb2wpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2xvZyhieXRlW10pYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9lcV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbmVfcm91dGVANyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbmVfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbmVfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbHRfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbGVfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbGVfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ2Vfcm91dGVAMjcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAyOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2Vfcm91dGVAMzAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5faW5pdF9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9pbml0X3JvdXRlQDM0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZ19yb3V0ZUAzOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2xvZ19yb3V0ZUA0MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXNfcm91dGVANDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlc19yb3V0ZUA0NCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfYWRkX3JvdXRlQDQ4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19ieXRlc19yb3V0ZUA1MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9ieXRlc19yb3V0ZUA1MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZXFfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fZXFfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9ieXRlX2VxX3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9ieXRlX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX3VpbnRuX25lX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9uZV9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbHRfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbHRfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sZV9yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbGVfcm91dGVAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9ndF9yb3V0ZUAyMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ3QKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ3Rfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9nZV9yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ2Vfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9pbml0X3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5faW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfaW5pdF9yb3V0ZUAzNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXNfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfZnJvbV9sb2dfcm91dGVANDA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fYnl0ZXNfcm91dGVANDE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWZpeGVkbnhtX2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlc19yb3V0ZUA0MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfaW5pdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19hZGRfcm91dGVANDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc3RyaW5nX2FkZAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19lcV9yb3V0ZUA0OToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fbG9nX3JvdXRlQDUyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2J5dGVzX3JvdXRlQDUzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Jvb2xfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NS02CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEKICAgIC8vIHJldHVybiBhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMy0xNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEtMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gcmV0dXJuIGFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIHJldHVybiBhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3LTM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MwogICAgLy8gcmV0dXJuIGFCeXRlLmVxdWFscyhiQnl0ZSkKICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NS00NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0OQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MQogICAgLy8gcmV0dXJuICFhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1My01NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1NwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5CiAgICAvLyByZXR1cm4gIWFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgICEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxLTYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjcKICAgIC8vIHJldHVybiAhYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjktNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NQogICAgLy8gcmV0dXJuICFhVWludE4uZXF1YWxzKGJVaW50TikKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gcmV0dXJuICFhQnl0ZS5lcXVhbHMoYkJ5dGUpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODUtODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMtOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5OQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPCBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxLTEwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDktMTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgYlVpbnROLm5hdGl2ZQogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3LTExOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPCBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNS0xMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzMtMTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQxLTE0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA8PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OS0xNTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPD0gYlVpbnROLm5hdGl2ZQogICAgYjw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1Ny0xNTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlIDw9IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NS0xNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczLTE3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc5CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEtMTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID4gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgaXRvYgogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OS0xOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPiBiVWludE4ubmF0aXZlCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTctMTk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMwogICAgLy8gcmV0dXJuIGFCeXRlLm5hdGl2ZSA+IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA1LTIwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMy0yMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxOQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gQmlnVWludChiVWludE4ubmF0aXZlKQogICAgYnRvaQogICAgaXRvYgogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl9iaWd1aW50bl9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjEtMjIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9iaWd1aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjcKICAgIC8vIHJldHVybiBCaWdVaW50KGFVaW50Ti5uYXRpdmUpID49IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5LTIzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+PSBiVWludE4ubmF0aXZlCiAgICBiPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM3LTIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPj0gYkJ5dGUubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA+PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDUtMjQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OAogICAgLy8gcmV0dXJuIG5ldyBVaW50TjwzMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgcHVzaGludCA0IC8vIDQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIHB1c2hpbnQgNCAvLyA0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5faW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTAtMjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9pbml0KGE6IGJ5dGVzKTogVWludE48MjU2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTMKICAgIC8vIHJldHVybiBuZXcgVWludE48MjU2PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBwdXNoaW50IDMyIC8vIDMyCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfaW5pdChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1LTI1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9pbml0KGE6IGJ5dGVzKTogQnl0ZSB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTgKICAgIC8vIHJldHVybiBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91aW50bl9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MC0yNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpOiBVaW50TjwzMj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYyCiAgICAvLyByZXR1cm4gVWludE4uZnJvbUJ5dGVzPDMyPihhKQogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NC0yNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpOiBVaW50TjwyNTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gcmV0dXJuIFVpbnROLmZyb21CeXRlczwyNTY+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OC0yNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcwCiAgICAvLyByZXR1cm4gQnl0ZS5mcm9tQnl0ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VpbnRuX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3Mi0yNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NAogICAgLy8gcmV0dXJuIFVpbnROLmZyb21Mb2c8MzI+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYtMjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc4CiAgICAvLyByZXR1cm4gVWludE4uZnJvbUxvZzwyNTY+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2Zyb21fbG9nKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2J5dGVfZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgwLTI4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9mcm9tX2xvZyhhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgyCiAgICAvLyByZXR1cm4gQnl0ZS5mcm9tTG9nKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91Zml4ZWRueG1fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWZpeGVkbnhtX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NC0yODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9ieXRlcyhhOiBVRml4ZWROeE08MzIsIDg+KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg2CiAgICAvLyByZXR1cm4gYS5ieXRlcwogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODgtMjg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXMoYTogVUZpeGVkTnhNPDI1NiwgMTY+KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkwCiAgICAvLyByZXR1cm4gYS5ieXRlcwogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkyLTI5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fYnl0ZXMoYTogYnl0ZXMpOiBVRml4ZWROeE08MzIsIDg+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NAogICAgLy8gcmV0dXJuIFVGaXhlZE54TS5mcm9tQnl0ZXM8MzIsIDg+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTYtMjk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlcyhhOiBieXRlcyk6IFVGaXhlZE54TTwyNTYsIDE2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTgKICAgIC8vIHJldHVybiBVRml4ZWROeE0uZnJvbUJ5dGVzPDI1NiwgMTY+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMC0zMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwzMiwgOD4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAyCiAgICAvLyByZXR1cm4gVUZpeGVkTnhNLmZyb21Mb2c8MzIsIDg+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNC0zMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwyNTYsIDE2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDYKICAgIC8vIHJldHVybiBVRml4ZWROeE0uZnJvbUxvZzwyNTYsIDE2PihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA4LTMwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2luaXQoYTogc3RyaW5nKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihgSGVsbG8sICR7YX1gKQogICAgcHVzaGJ5dGVzICJIZWxsbywgIgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMtMzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfYWRkKGE6IFN0ciwgYjogU3RyKTogU3RyIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5uYXRpdmUuY29uY2F0KGIubmF0aXZlKQogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE2CiAgICAvLyByZXR1cm4gbmV3IFN0cihyZXN1bHQpCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3N0cmluZ19lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgtMzE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZXEoYTogU3RyLCBiOiBTdHIpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMAogICAgLy8gcmV0dXJuIGEuZXF1YWxzKGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMi0zMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19ieXRlcyhhOiBzdHJpbmcpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG5ldyBTdHIoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjUKICAgIC8vIHJldHVybiByZXN1bHQuYnl0ZXMKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjctMzI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjkKICAgIC8vIHJldHVybiBTdHIuZnJvbUJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMS0zMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2xvZyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzMKICAgIC8vIHJldHVybiBTdHIuZnJvbUxvZyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNS0zMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfYnl0ZXMoYTogQm9vbCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNwogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5LTM0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIHJldHVybiBCb29sLmZyb21CeXRlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0My0zNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfZnJvbV9sb2coYTogYnl0ZXMpOiBCb29sIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0NQogICAgLy8gcmV0dXJuIEJvb2wuZnJvbUxvZyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEFSQzQgcHJlZml4IGlzIHZhbGlkCiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSA4IDY0IDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NSAweDAwCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OAogICAgcHVzaGJ5dGVzcyAweDk2ZjE0MTE2IDB4ZWQ2NjYwOTYgMHgyY2EwMzUyYiAweDg1OTA3ZDQwIDB4NGViMmFmNGEgMHgyY2JlYzQ1YiAweDA3NjY2ZmQ5IDB4MzcwYmFiZDMgMHgyYjZiM2VmMCAweDI3ZTIxYTk4IDB4MzM5ZGE5N2MgMHg3ODk4ZWQ5NyAweDFmMTMwY2VjIDB4Yzc0ODY2NGUgMHhhMmJhYzE0YiAweDdhNDYwY2IxIDB4ZGNhYjFmMDEgMHg5N2Q5MDY0ZCAweGNlMDZjMmEwIDB4N2MxMWUzNzUgMHhkY2RiY2VlMCAweDc3YTRiNjhkIDB4NGY1NDA2MjYgMHgwOTVhZWQ0MSAweGRmNzhjZGM2IDB4ZTNiN2U5MTggMHg1NTMzNzAwOCAweDliYjFjZDY2IDB4ODE0ODRkOWQgMHg3OWU5Y2IwMyAweDlhMDNkZjEwIDB4ZDNmMGU0NGIgMHg2NzNkYjJiZCAweDk4MmRiMjMzIDB4YWZmYmRmMGUgMHg4ZTRhMzBmNyAweDI4OGFmNzZlIDB4OGJkODRhMDQgMHhmY2Q1NWUxZiAweDBmMTU3NGZlIDB4YjJjYjEzYmUgMHhkMDU5ZWVhNyAweDRjYzRjMTU3IDB4M2QxN2FjNmUgMHhmN2YzZDVmYyAweGY4YzhmOGQ1IDB4NDNmNzE2MmEgMHg0MmUwOTA3NSAweGQ5NTZmNTc1IDB4NmMwMTYwZGYgMHhhODkwMTUwYiAweDBiMmY0YzNmIDB4OWRiOWQzMjcgMHhlNGQ5NTBhMSAvLyBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfZXEoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9sdChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfbGUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2d0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9nZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9pbml0KGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9pbml0KGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9pbml0KGJ5dGVbXSlieXRlIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDMyIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhieXRlW10pYnl0ZSIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9sb2coYnl0ZVtdKWJ5dGUiLCBtZXRob2QgInZlcmlmeV91Zml4ZWRueG1fYnl0ZXModWZpeGVkMzJ4OClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXModWZpeGVkMjU2eDE2KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGJ5dGVbXSl1Zml4ZWQzMng4IiwgbWV0aG9kICJ2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMoYnl0ZVtdKXVmaXhlZDI1NngxNiIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMzJ4OCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMjU2eDE2IiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2luaXQoc3RyaW5nKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19hZGQoc3RyaW5nLHN0cmluZylzdHJpbmciLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZXEoc3RyaW5nLHN0cmluZylib29sIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2J5dGVzKHN0cmluZylieXRlW10iLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhieXRlW10pc3RyaW5nIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nKGJ5dGVbXSlzdHJpbmciLCBtZXRob2QgInZlcmlmeV9ib29sX2J5dGVzKGJvb2wpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2xvZyhieXRlW10pYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9lcV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbmVfcm91dGVANyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbmVfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbmVfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbHRfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbGVfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbGVfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ2Vfcm91dGVAMjcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAyOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2Vfcm91dGVAMzAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5faW5pdF9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9pbml0X3JvdXRlQDM0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZ19yb3V0ZUAzOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2xvZ19yb3V0ZUA0MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXNfcm91dGVANDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlc19yb3V0ZUA0NCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfYWRkX3JvdXRlQDQ4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19ieXRlc19yb3V0ZUA1MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9ieXRlc19yb3V0ZUA1MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZXFfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZXFfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9uZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sdF9yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbHRfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0X3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfbHRfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sZV9yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbGVfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlX3JvdXRlQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9ieXRlX2xlX3JvdXRlQDIxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fYmlndWludG5fZ3QKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9ieXRlX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9nZV9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ2Vfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlX3JvdXRlQDMwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZ2Vfcm91dGVAMzE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9pbml0X3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2luaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9pbml0X3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2luaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2luaXRfcm91dGVAMzQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzX3JvdXRlQDM3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fZnJvbV9sb2dfcm91dGVAMzk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fbG9nX3JvdXRlQDQwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fYnl0ZXNfcm91dGVANDE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91Zml4ZWRueG1fYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2FkZF9yb3V0ZUA0ODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19hZGQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlc19yb3V0ZUA1MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2J5dGVzX3JvdXRlQDUzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYm9vbF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fYnl0ZXNfcm91dGVANTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2xvZ19yb3V0ZUA1NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgaW50Y18zIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUtNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExCiAgICAvLyByZXR1cm4gYVVpbnROID09PSBiVWludE4KICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMy0xNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEtMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gcmV0dXJuIGFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIHJldHVybiBhVWludE4gPT09IGJVaW50TgogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzctMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzCiAgICAvLyByZXR1cm4gYUJ5dGUgPT09IGJCeXRlCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDUtNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIHJldHVybiBhVWludE4gIT09IGJVaW50TgogICAgIT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUzLTU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkKICAgIC8vIHJldHVybiAhYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEtNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NwogICAgLy8gcmV0dXJuICFhVWludE4uYnl0ZXMuZXF1YWxzKGJVaW50Ti5ieXRlcykKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyByZXR1cm4gYVVpbnROICE9PSBiVWludE4KICAgICE9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gcmV0dXJuIGFCeXRlICE9PSBiQnl0ZQogICAgIT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1LTg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzLTk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgQmlnVWludChiVWludE4ubmF0aXZlKQogICAgYnRvaQogICAgaXRvYgogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMS0xMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNwogICAgLy8gcmV0dXJuIEJpZ1VpbnQoYVVpbnROLm5hdGl2ZSkgPCBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA5LTExMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE1CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8IGJVaW50Ti5uYXRpdmUKICAgIGI8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNy0xMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlIDwgYkJ5dGUubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUtMTI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzLTEzNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzOAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM5CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8PSBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MS0xNDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NwogICAgLy8gcmV0dXJuIEJpZ1VpbnQoYVVpbnROLm5hdGl2ZSkgPD0gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgaXRvYgogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDktMTUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IGJVaW50Ti5uYXRpdmUKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTctMTU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MwogICAgLy8gcmV0dXJuIGFCeXRlLm5hdGl2ZSA8PSBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUtMTY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3My0xNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPiBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxLTE4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA+IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODktMTkwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID4gYlVpbnROLm5hdGl2ZQogICAgYj4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3LTE5OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPiBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNS0yMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID49IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTMtMjE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID49IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxLTIyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA+PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOS0yMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gYlVpbnROLm5hdGl2ZQogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNy0yMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlID49IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9pbml0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VpbnRuX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ1LTI0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5faW5pdChhOiBieXRlcyk6IFVpbnROPDMyPiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDgKICAgIC8vIHJldHVybiBuZXcgVWludE48MzI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIHB1c2hpbnQgNCAvLyA0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBwdXNoaW50IDQgLy8gNAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9pbml0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRuX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwLTI1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5faW5pdChhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUzCiAgICAvLyByZXR1cm4gbmV3IFVpbnROPDI1Nj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgcHVzaGludCAzMiAvLyAzMgogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgcHVzaGludCAzMiAvLyAzMgogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9pbml0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1NS0yNTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfaW5pdChhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU4CiAgICAvLyByZXR1cm4gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5fZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAtMjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MgogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVaW50TjwzMj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0LTI2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFVpbnROPDI1Nj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OC0yNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcwCiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PEJ5dGU+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91aW50bl9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzItMjczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9mcm9tX2xvZyhhOiBieXRlcyk6IFVpbnROPDMyPiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzQKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VWludE48MzI+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2LTI3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fZnJvbV9sb2coYTogYnl0ZXMpOiBVaW50TjwyNTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3OAogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVaW50TjwyNTY+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MC0yODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9sb2coYTogYnl0ZXMpOiBCeXRlIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MgogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxCeXRlPihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWZpeGVkbnhtX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQtMjg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91Zml4ZWRueG1fYnl0ZXMoYTogVUZpeGVkTnhNPDMyLCA4Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NgogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4LTI4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzKGE6IFVGaXhlZE54TTwyNTYsIDE2Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MAogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Mi0yOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDMyLCA4PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTQKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VUZpeGVkTnhNPDMyLCA4Pj4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Ni0yOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDI1NiwgMTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5OAogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVRml4ZWROeE08MjU2LCAxNj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMC0zMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwzMiwgOD4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAyCiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFVGaXhlZE54TTwzMiwgOD4+KGEsICdsb2cnKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEJ5dGVzIGhhcyB2YWxpZCBwcmVmaXgKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNC0zMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwyNTYsIDE2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDYKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VUZpeGVkTnhNPDI1NiwgMTY+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA4LTMwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2luaXQoYTogc3RyaW5nKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihgSGVsbG8sICR7YX1gKQogICAgcHVzaGJ5dGVzICJIZWxsbywgIgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMtMzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfYWRkKGE6IFN0ciwgYjogU3RyKTogU3RyIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5uYXRpdmUuY29uY2F0KGIubmF0aXZlKQogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE2CiAgICAvLyByZXR1cm4gbmV3IFN0cihyZXN1bHQpCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3N0cmluZ19lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgtMzE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZXEoYTogU3RyLCBiOiBTdHIpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMAogICAgLy8gcmV0dXJuIGEgPT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIyLTMyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2J5dGVzKGE6IHN0cmluZyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNQogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNy0zMjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzKGE6IGJ5dGVzKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyOQogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxTdHI+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMS0zMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2xvZyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzMKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8U3RyPihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNS0zMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfYnl0ZXMoYTogQm9vbCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNwogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5LTM0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qm9vbD4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYm9vbF9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMtMzQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ib29sX2Zyb21fbG9nKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDUKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qm9vbD4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCg==", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" }, "state": { diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc56.json b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc56.json new file mode 100644 index 0000000..ff6a4bf --- /dev/null +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc56.json @@ -0,0 +1,1522 @@ +{ + "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": {} + } + ], + "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": [ + 2956, + 2973, + 2990, + 3031, + 3048, + 3141, + 3170 + ], + "errorMessage": "Bytes has valid prefix" + }, + { + "pc": [ + 418, + 451, + 484, + 517, + 550, + 583, + 616, + 649, + 682, + 715, + 748, + 781, + 814, + 847, + 880, + 913, + 946, + 979, + 1012, + 1045, + 1078, + 1111, + 1144, + 1177, + 1210, + 1243, + 1276, + 1309, + 1342, + 1375, + 1408, + 1430, + 1452, + 1474, + 1496, + 1518, + 1540, + 1562, + 1584, + 1606, + 1633, + 1660, + 1682, + 1704, + 1726, + 1748, + 1770, + 1792, + 1819, + 1849, + 1871, + 1893, + 1920, + 1942 + ], + "errorMessage": "OnCompletion is not NoOp" + }, + { + "pc": [ + 1969 + ], + "errorMessage": "can only call when creating" + }, + { + "pc": [ + 421, + 454, + 487, + 520, + 553, + 586, + 619, + 652, + 685, + 718, + 751, + 784, + 817, + 850, + 883, + 916, + 949, + 982, + 1015, + 1048, + 1081, + 1114, + 1147, + 1180, + 1213, + 1246, + 1279, + 1312, + 1345, + 1378, + 1411, + 1433, + 1455, + 1477, + 1499, + 1521, + 1543, + 1565, + 1587, + 1609, + 1636, + 1663, + 1685, + 1707, + 1729, + 1751, + 1773, + 1795, + 1822, + 1852, + 1874, + 1896, + 1923, + 1945 + ], + "errorMessage": "can only call when not creating" + }, + { + "pc": [ + 1982, + 1995, + 2011, + 2022, + 2038, + 2049, + 2065, + 2078, + 2094, + 2107, + 2123, + 2136, + 2152, + 2163, + 2180, + 2191, + 2208, + 2221, + 2237, + 2250, + 2266, + 2279, + 2299, + 2310, + 2328, + 2339, + 2358, + 2371, + 2387, + 2400, + 2420, + 2433, + 2453, + 2464, + 2482, + 2493, + 2512, + 2525, + 2541, + 2554, + 2574, + 2587, + 2607, + 2618, + 2636, + 2647, + 2666, + 2679, + 2695, + 2708, + 2728, + 2741, + 2761, + 2772, + 2790, + 2801, + 2820, + 2833, + 2849, + 2862, + 2883, + 2900, + 2916 + ], + "errorMessage": "overflow" + } + ], + "pcOffsetMethod": "none" + }, + "clear": { + "sourceInfo": [], + "pcOffsetMethod": "none" + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSA4IDY0IDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NSAweDAwCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OAogICAgcHVzaGJ5dGVzcyAweDk2ZjE0MTE2IDB4ZWQ2NjYwOTYgMHgyY2EwMzUyYiAweDg1OTA3ZDQwIDB4NGViMmFmNGEgMHgyY2JlYzQ1YiAweDA3NjY2ZmQ5IDB4MzcwYmFiZDMgMHgyYjZiM2VmMCAweDI3ZTIxYTk4IDB4MzM5ZGE5N2MgMHg3ODk4ZWQ5NyAweDFmMTMwY2VjIDB4Yzc0ODY2NGUgMHhhMmJhYzE0YiAweDdhNDYwY2IxIDB4ZGNhYjFmMDEgMHg5N2Q5MDY0ZCAweGNlMDZjMmEwIDB4N2MxMWUzNzUgMHhkY2RiY2VlMCAweDc3YTRiNjhkIDB4NGY1NDA2MjYgMHgwOTVhZWQ0MSAweGRmNzhjZGM2IDB4ZTNiN2U5MTggMHg1NTMzNzAwOCAweDliYjFjZDY2IDB4ODE0ODRkOWQgMHg3OWU5Y2IwMyAweDlhMDNkZjEwIDB4ZDNmMGU0NGIgMHg2NzNkYjJiZCAweDk4MmRiMjMzIDB4YWZmYmRmMGUgMHg4ZTRhMzBmNyAweDI4OGFmNzZlIDB4OGJkODRhMDQgMHhmY2Q1NWUxZiAweDBmMTU3NGZlIDB4YjJjYjEzYmUgMHhkMDU5ZWVhNyAweDRjYzRjMTU3IDB4M2QxN2FjNmUgMHhmN2YzZDVmYyAweGY4YzhmOGQ1IDB4NDNmNzE2MmEgMHg0MmUwOTA3NSAweGQ5NTZmNTc1IDB4NmMwMTYwZGYgMHhhODkwMTUwYiAweDBiMmY0YzNmIDB4OWRiOWQzMjcgMHhlNGQ5NTBhMSAvLyBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfZXEoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9sdChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfbGUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2d0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9nZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9pbml0KGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9pbml0KGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9pbml0KGJ5dGVbXSlieXRlIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDMyIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhieXRlW10pYnl0ZSIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9sb2coYnl0ZVtdKWJ5dGUiLCBtZXRob2QgInZlcmlmeV91Zml4ZWRueG1fYnl0ZXModWZpeGVkMzJ4OClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXModWZpeGVkMjU2eDE2KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGJ5dGVbXSl1Zml4ZWQzMng4IiwgbWV0aG9kICJ2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMoYnl0ZVtdKXVmaXhlZDI1NngxNiIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMzJ4OCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMjU2eDE2IiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2luaXQoc3RyaW5nKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19hZGQoc3RyaW5nLHN0cmluZylzdHJpbmciLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZXEoc3RyaW5nLHN0cmluZylib29sIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2J5dGVzKHN0cmluZylieXRlW10iLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhieXRlW10pc3RyaW5nIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nKGJ5dGVbXSlzdHJpbmciLCBtZXRob2QgInZlcmlmeV9ib29sX2J5dGVzKGJvb2wpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2xvZyhieXRlW10pYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9lcV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbmVfcm91dGVANyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbmVfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbmVfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbHRfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbGVfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbGVfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ2Vfcm91dGVAMjcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAyOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2Vfcm91dGVAMzAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5faW5pdF9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9pbml0X3JvdXRlQDM0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZ19yb3V0ZUAzOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2xvZ19yb3V0ZUA0MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXNfcm91dGVANDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlc19yb3V0ZUA0NCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfYWRkX3JvdXRlQDQ4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19ieXRlc19yb3V0ZUA1MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9ieXRlc19yb3V0ZUA1MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZXFfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZXFfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9uZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sdF9yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbHRfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0X3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfbHRfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sZV9yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbGVfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlX3JvdXRlQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9ieXRlX2xlX3JvdXRlQDIxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fYmlndWludG5fZ3QKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9ieXRlX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9nZV9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ2Vfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlX3JvdXRlQDMwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZ2Vfcm91dGVAMzE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9pbml0X3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2luaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9pbml0X3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2luaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2luaXRfcm91dGVAMzQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzX3JvdXRlQDM3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fZnJvbV9sb2dfcm91dGVAMzk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fbG9nX3JvdXRlQDQwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fYnl0ZXNfcm91dGVANDE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91Zml4ZWRueG1fYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2FkZF9yb3V0ZUA0ODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19hZGQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlc19yb3V0ZUA1MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2J5dGVzX3JvdXRlQDUzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYm9vbF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fYnl0ZXNfcm91dGVANTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2xvZ19yb3V0ZUA1NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgaW50Y18zIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUtNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExCiAgICAvLyByZXR1cm4gYVVpbnROID09PSBiVWludE4KICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMy0xNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEtMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gcmV0dXJuIGFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIHJldHVybiBhVWludE4gPT09IGJVaW50TgogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzctMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzCiAgICAvLyByZXR1cm4gYUJ5dGUgPT09IGJCeXRlCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDUtNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIHJldHVybiBhVWludE4gIT09IGJVaW50TgogICAgIT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUzLTU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkKICAgIC8vIHJldHVybiAhYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEtNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NwogICAgLy8gcmV0dXJuICFhVWludE4uYnl0ZXMuZXF1YWxzKGJVaW50Ti5ieXRlcykKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyByZXR1cm4gYVVpbnROICE9PSBiVWludE4KICAgICE9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gcmV0dXJuIGFCeXRlICE9PSBiQnl0ZQogICAgIT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1LTg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzLTk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgQmlnVWludChiVWludE4ubmF0aXZlKQogICAgYnRvaQogICAgaXRvYgogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMS0xMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNwogICAgLy8gcmV0dXJuIEJpZ1VpbnQoYVVpbnROLm5hdGl2ZSkgPCBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA5LTExMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE1CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8IGJVaW50Ti5uYXRpdmUKICAgIGI8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNy0xMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlIDwgYkJ5dGUubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUtMTI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzLTEzNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzOAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM5CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8PSBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MS0xNDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NwogICAgLy8gcmV0dXJuIEJpZ1VpbnQoYVVpbnROLm5hdGl2ZSkgPD0gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgaXRvYgogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDktMTUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IGJVaW50Ti5uYXRpdmUKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTctMTU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MwogICAgLy8gcmV0dXJuIGFCeXRlLm5hdGl2ZSA8PSBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUtMTY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3My0xNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPiBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxLTE4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA+IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODktMTkwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID4gYlVpbnROLm5hdGl2ZQogICAgYj4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3LTE5OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPiBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNS0yMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID49IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTMtMjE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID49IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxLTIyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA+PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOS0yMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gYlVpbnROLm5hdGl2ZQogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNy0yMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlID49IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9pbml0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VpbnRuX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ1LTI0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5faW5pdChhOiBieXRlcyk6IFVpbnROPDMyPiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDgKICAgIC8vIHJldHVybiBuZXcgVWludE48MzI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIHB1c2hpbnQgNCAvLyA0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBwdXNoaW50IDQgLy8gNAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9pbml0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRuX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwLTI1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5faW5pdChhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUzCiAgICAvLyByZXR1cm4gbmV3IFVpbnROPDI1Nj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgcHVzaGludCAzMiAvLyAzMgogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgcHVzaGludCAzMiAvLyAzMgogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9pbml0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1NS0yNTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfaW5pdChhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU4CiAgICAvLyByZXR1cm4gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5fZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAtMjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MgogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVaW50TjwzMj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0LTI2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFVpbnROPDI1Nj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OC0yNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcwCiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PEJ5dGU+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91aW50bl9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzItMjczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9mcm9tX2xvZyhhOiBieXRlcyk6IFVpbnROPDMyPiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzQKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VWludE48MzI+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2LTI3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fZnJvbV9sb2coYTogYnl0ZXMpOiBVaW50TjwyNTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3OAogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVaW50TjwyNTY+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MC0yODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9sb2coYTogYnl0ZXMpOiBCeXRlIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MgogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxCeXRlPihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWZpeGVkbnhtX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQtMjg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91Zml4ZWRueG1fYnl0ZXMoYTogVUZpeGVkTnhNPDMyLCA4Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NgogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4LTI4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzKGE6IFVGaXhlZE54TTwyNTYsIDE2Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MAogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Mi0yOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDMyLCA4PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTQKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VUZpeGVkTnhNPDMyLCA4Pj4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Ni0yOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDI1NiwgMTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5OAogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVRml4ZWROeE08MjU2LCAxNj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMC0zMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwzMiwgOD4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAyCiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFVGaXhlZE54TTwzMiwgOD4+KGEsICdsb2cnKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEJ5dGVzIGhhcyB2YWxpZCBwcmVmaXgKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNC0zMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwyNTYsIDE2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDYKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VUZpeGVkTnhNPDI1NiwgMTY+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA4LTMwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2luaXQoYTogc3RyaW5nKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihgSGVsbG8sICR7YX1gKQogICAgcHVzaGJ5dGVzICJIZWxsbywgIgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMtMzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfYWRkKGE6IFN0ciwgYjogU3RyKTogU3RyIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5uYXRpdmUuY29uY2F0KGIubmF0aXZlKQogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE2CiAgICAvLyByZXR1cm4gbmV3IFN0cihyZXN1bHQpCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3N0cmluZ19lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgtMzE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZXEoYTogU3RyLCBiOiBTdHIpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMAogICAgLy8gcmV0dXJuIGEgPT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIyLTMyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2J5dGVzKGE6IHN0cmluZyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNQogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNy0zMjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzKGE6IGJ5dGVzKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyOQogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxTdHI+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMS0zMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2xvZyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzMKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8U3RyPihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNS0zMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfYnl0ZXMoYTogQm9vbCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNwogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5LTM0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qm9vbD4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYm9vbF9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMtMzQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ib29sX2Zyb21fbG9nKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDUKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qm9vbD4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" + }, + "events": [], + "templateVariables": {} +} \ No newline at end of file From 232f4775414087979341260f16ca6dcca8dc1360 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Wed, 20 Nov 2024 17:39:20 +0800 Subject: [PATCH 62/85] feat: implement stubs for the following arc4 types - static array - dynamic array - address - tuple - struct - dynamic bytes - static bytes --- src/impl/encoded-types.ts | 889 ++++++++++++++++++++++++++++++- src/util.ts | 4 + tests/arc4/address.spec.ts | 83 +++ tests/arc4/dynamic-array.spec.ts | 625 ++++++++++++++++++++++ tests/arc4/dynamic-bytes.spec.ts | 51 ++ tests/arc4/static-array.spec.ts | 559 +++++++++++++++++++ tests/arc4/static-bytes.spec.ts | 56 ++ tests/arc4/struct.spec.ts | 319 +++++++++++ tests/arc4/tuple.spec.ts | 360 +++++++++++++ 9 files changed, 2921 insertions(+), 25 deletions(-) create mode 100644 tests/arc4/address.spec.ts create mode 100644 tests/arc4/dynamic-array.spec.ts create mode 100644 tests/arc4/dynamic-bytes.spec.ts create mode 100644 tests/arc4/static-array.spec.ts create mode 100644 tests/arc4/static-bytes.spec.ts create mode 100644 tests/arc4/struct.spec.ts create mode 100644 tests/arc4/tuple.spec.ts diff --git a/src/impl/encoded-types.ts b/src/impl/encoded-types.ts index f4d579e..cf8578b 100644 --- a/src/impl/encoded-types.ts +++ b/src/impl/encoded-types.ts @@ -1,11 +1,27 @@ -import { BigUintCompat, Bytes, bytes, internal, StringCompat, Uint64Compat } from '@algorandfoundation/algorand-typescript' -import { ARC4Encoded, BitSize, Bool, Byte, Str, UFixedNxM, UintN } from '@algorandfoundation/algorand-typescript/arc4' +import { Account, BigUintCompat, Bytes, bytes, internal, StringCompat, uint64, Uint64Compat } from '@algorandfoundation/algorand-typescript' +import { + Address, + ARC4Encoded, + BitSize, + Bool, + Byte, + DynamicArray, + DynamicBytes, + StaticArray, + StaticBytes, + Str, + Struct, + Tuple, + UFixedNxM, + UintN, +} from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' +import { decodeAddress } from 'algosdk' import assert from 'assert' import { ABI_RETURN_VALUE_LOG_PREFIX, BITS_IN_BYTE, UINT64_SIZE } from '../constants' import { fromBytes, TypeInfo } from '../encoders' import { DeliberateAny } from '../typescript-helpers' -import { asBigUint, asBigUintCls, asBytesCls, asUint64, asUint8Array } from '../util' +import { asBigUint, asBigUintCls, asBytesCls, asUint64, asUint8Array, conactUint8Arrays, uint8ArrayToNumber } from '../util' const ABI_LENGTH_SIZE = 2 const maxBigIntValue = (bitSize: number) => 2n ** BigInt(bitSize) - 1n @@ -17,10 +33,10 @@ export class UintNImpl extends UintN { private bitSize: N typeInfo: TypeInfo - constructor(typeInfoString: string, v?: CompatForArc4Int) { + constructor(typeInfo: TypeInfo | string, v?: CompatForArc4Int) { super() - this.typeInfo = JSON.parse(typeInfoString) - this.bitSize = parseInt((this.typeInfo.genericArgs as TypeInfo[])![0].name, 10) as N + 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}`) @@ -57,11 +73,14 @@ export class UintNImpl extends UintN { assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') bytesValue = bytesValue.slice(4) } - const typeInfoString = typeof typeInfo === 'string' ? typeInfo : JSON.stringify(typeInfo) - const result = new UintNImpl(typeInfoString) + const result = new UintNImpl(typeInfo) result.value = asUint8Array(bytesValue) return result } + + static getMaxBitsLength(typeInfo: TypeInfo): BitSize { + return parseInt((typeInfo.genericArgs as TypeInfo[])![0].name, 10) as BitSize + } } const regExpNxM = (maxPrecision: number) => new RegExp(`^\\d*\\.?\\d{0,${maxPrecision}}$`) @@ -73,11 +92,11 @@ export class UFixedNxMImpl extends UFixedNx private precision: M private typeInfo: TypeInfo - constructor(typeInfoString: string, v: `${number}.${number}`) { + constructor(typeInfo: TypeInfo | string, v: `${number}.${number}`) { super(v) - this.typeInfo = JSON.parse(typeInfoString) + this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo const genericArgs = this.typeInfo.genericArgs as uFixedNxMGenericArgs - this.bitSize = parseInt(genericArgs.n.name, 10) as N + this.bitSize = UFixedNxMImpl.getMaxBitsLength(this.typeInfo) as N this.precision = parseInt(genericArgs.m.name, 10) as M const trimmedValue = trimTrailingDecimalZeros(v) @@ -116,19 +135,23 @@ export class UFixedNxMImpl extends UFixedNx assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') bytesValue = bytesValue.slice(4) } - const typeInfoString = typeof typeInfo === 'string' ? typeInfo : JSON.stringify(typeInfo) - const result = new UFixedNxMImpl(typeInfoString, '0.0') + const result = new UFixedNxMImpl(typeInfo, '0.0') result.value = asUint8Array(bytesValue) return result } + + static getMaxBitsLength(typeInfo: TypeInfo): BitSize { + const genericArgs = typeInfo.genericArgs as uFixedNxMGenericArgs + return parseInt(genericArgs.n.name, 10) as BitSize + } } export class ByteImpl extends Byte { private value: UintNImpl<8> - constructor(typeInfoString: string, v?: CompatForArc4Int<8>) { + constructor(typeInfo: TypeInfo | string, v?: CompatForArc4Int<8>) { super(v) - this.value = new UintNImpl<8>(typeInfoString, v) + this.value = new UintNImpl<8>(typeInfo, v) } get native() { @@ -152,17 +175,20 @@ export class ByteImpl extends Byte { prefix: 'none' | 'log' = 'none', ): ByteImpl { const uintNValue = UintNImpl.fromBytesImpl(value, typeInfo, prefix) as UintNImpl<8> - const typeInfoString = typeof typeInfo === 'string' ? typeInfo : JSON.stringify(typeInfo) - const result = new ByteImpl(typeInfoString) + const result = new ByteImpl(typeInfo) result.value = uintNValue return result } + + static getMaxBitsLength(typeInfo: TypeInfo): BitSize { + return UintNImpl.getMaxBitsLength(typeInfo) + } } export class StrImpl extends Str { private value: Uint8Array - constructor(_typeInfoString: string, s?: StringCompat) { + constructor(_typeInfo: TypeInfo | string, s?: StringCompat) { super() const bytesValue = asBytesCls(s ?? '') const bytesLength = encodeLength(bytesValue.length.asNumber()) @@ -178,7 +204,7 @@ 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 internal.errors.CodeError(`Expected expression of type Str, got ${(other as object).constructor.name}`) } return this.bytes.equals(other.bytes) } @@ -193,19 +219,18 @@ export class StrImpl extends Str { assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') bytesValue = bytesValue.slice(4) } - const typeInfoString = typeof typeInfo === 'string' ? typeInfo : JSON.stringify(typeInfo) - const result = new StrImpl(typeInfoString) + const result = new StrImpl(typeInfo) result.value = asUint8Array(bytesValue) return result } } + const TRUE_BIGINT_VALUE = 128n const FALSE_BIGINT_VALUE = 0n - export class BoolImpl extends Bool { private value: Uint8Array - constructor(_typeInfoString: string, v?: boolean) { + constructor(_typeInfo: TypeInfo | string, v?: boolean) { super(v) this.value = encodingUtil.bigIntToUint8Array(v ? TRUE_BIGINT_VALUE : FALSE_BIGINT_VALUE, 1) } @@ -214,6 +239,13 @@ export class BoolImpl extends Bool { return encodingUtil.uint8ArrayToBigInt(this.value) === TRUE_BIGINT_VALUE } + equals(other: this): boolean { + if (!(other instanceof BoolImpl)) { + throw new internal.errors.CodeError(`Expected expression of type Bool, got ${(other as object).constructor.name}`) + } + return this.bytes.equals(other.bytes) + } + get bytes(): bytes { return Bytes(this.value) } @@ -228,13 +260,813 @@ export class BoolImpl extends Bool { assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') bytesValue = bytesValue.slice(4) } - const typeInfoString = typeof typeInfo === 'string' ? typeInfo : JSON.stringify(typeInfo) - const result = new BoolImpl(typeInfoString) + const result = new BoolImpl(typeInfo) result.value = asUint8Array(bytesValue) return result } } +const areAllARC4Encoded = (items: T[]): items is T[] => items.every((item) => item instanceof ARC4Encoded) +const checkItemTypeName = (type: TypeInfo, value: ARC4Encoded) => { + const typeName = trimGenericTypeName(type.name) + const validTypeNames = [typeName, `${typeName}Impl`] + assert(validTypeNames.includes(value.constructor.name), `item must be of type ${typeName}, not ${value.constructor.name}`) +} +type StaticArrayGenericArgs = { elementType: TypeInfo; size: TypeInfo } +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') + } 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 Reflect.get(target, prop) + }, + 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) { + target.setItem(idx, value) + return true + } + internal.errors.avmError('Index out of bounds') + } + + return Reflect.set(target, prop, value) + }, +}) +export class StaticArrayImpl extends StaticArray { + private value?: TItem[] + private uint8ArrayValue?: Uint8Array + private typeInfo: TypeInfo + private size: number + genericArgs: StaticArrayGenericArgs + + constructor(typeInfo: TypeInfo | string, ...items: TItem[] & { length: TLength }) + constructor(typeInfo: TypeInfo | string, ...items: TItem[]) + constructor(typeInfo: TypeInfo | string, ...items: TItem[] & { length: TLength }) { + super(...items) + 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}`) + } + + assert(areAllARC4Encoded(items), 'expected ARC4 type') + + items.forEach((item) => { + checkItemTypeName(this.genericArgs.elementType, item) + }) + + this.value = items.length ? items : undefined + + return new Proxy(this, arrayProxyHandler()) as StaticArrayImpl + } + + get bytes(): bytes { + return Bytes(this.uint8ArrayValue ?? encode(this.items)) + } + + 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}`) + } + return this.bytes.equals(other.bytes) + } + + get length(): uint64 { + return this.size + } + + get items(): TItem[] { + if (this.uint8ArrayValue) { + const childTypes = Array(this.size).fill(this.genericArgs.elementType) + this.value = decode(this.uint8ArrayValue, childTypes) as TItem[] + this.uint8ArrayValue = undefined + return this.value + } else if (this.value) { + this.uint8ArrayValue = undefined + return this.value + } + throw new internal.errors.CodeError('value is not set') + } + + setItem(index: number, value: TItem): void { + this.items[index] = value + } + + copy(): StaticArrayImpl { + return StaticArrayImpl.fromBytesImpl(this.bytes, JSON.stringify(this.typeInfo)) as StaticArrayImpl + } + + static fromBytesImpl( + value: internal.primitives.StubBytesCompat | Uint8Array, + typeInfo: string | TypeInfo, + prefix: 'none' | 'log' = 'none', + ): StaticArrayImpl { + let bytesValue = asBytesCls(value) + if (prefix === 'log') { + assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') + bytesValue = bytesValue.slice(4) + } + const result = new StaticArrayImpl(typeInfo) + result.uint8ArrayValue = asUint8Array(bytesValue) + return result + } + + static getMaxBytesLength(typeInfo: TypeInfo): number { + const genericArgs = typeInfo.genericArgs as StaticArrayGenericArgs + const arraySize = parseInt(genericArgs.size.name, 10) + const childTypes = Array(arraySize).fill(genericArgs.elementType) + let i = 0 + let size = 0 + if (genericArgs.elementType.name === 'Bool') { + while (i < childTypes.length) { + const after = findBoolTypes(childTypes, i, 1) + const boolNum = after + 1 + size += Math.floor(boolNum / BITS_IN_BYTE) + size += boolNum % BITS_IN_BYTE ? 1 : 0 + i += after + 1 + } + } else { + size = getMaxLengthOfStaticContentType(genericArgs.elementType) * arraySize + } + return size + } +} + +export class AddressImpl extends Address { + private typeInfo: TypeInfo + private value: StaticArrayImpl + + constructor(typeInfo: TypeInfo | string, value?: Account | string | bytes) { + super(value) + let uint8ArrayValue: Uint8Array + if (value === undefined) { + uint8ArrayValue = new Uint8Array(32) + } else if (typeof value === 'string') { + uint8ArrayValue = decodeAddress(value).publicKey + } else if (internal.primitives.isBytes(value)) { + uint8ArrayValue = internal.primitives.getUint8Array(value) + } else { + uint8ArrayValue = internal.primitives.getUint8Array(value.bytes) + } + internal.errors.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 + return new Proxy(this, arrayProxyHandler()) as AddressImpl + } + + get bytes(): bytes { + return this.value.bytes + } + + 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}`) + } + return this.bytes.equals(other.bytes) + } + + get length(): uint64 { + return 32 + } + + get native(): Account { + return Account(this.value.bytes) + } + + get items(): ByteImpl[] { + return this.value.items + } + + setItem(_index: number, _value: ByteImpl): void { + throw new internal.errors.CodeError('Address is immutable') + } + + static fromBytesImpl( + value: internal.primitives.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 + return result + } + + static getMaxBytesLength(typeInfo: TypeInfo): number { + return StaticArrayImpl.getMaxBytesLength(typeInfo) + } +} + +type DynamicArrayGenericArgs = { elementType: TypeInfo } +const readLength = (value: Uint8Array): readonly [number, Uint8Array] => { + const length = Number(encodingUtil.uint8ArrayToBigInt(value.slice(0, ABI_LENGTH_SIZE))) + const data = value.slice(ABI_LENGTH_SIZE) + return [length, data] +} +export class DynamicArrayImpl extends DynamicArray { + private value?: TItem[] + private uint8ArrayValue?: Uint8Array + private typeInfo: TypeInfo + genericArgs: DynamicArrayGenericArgs + + constructor(typeInfo: TypeInfo | string, ...items: TItem[]) { + super(...items) + this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo + this.genericArgs = this.typeInfo.genericArgs as DynamicArrayGenericArgs + + assert(areAllARC4Encoded(items), 'expected ARC4 type') + + items.forEach((item) => { + checkItemTypeName(this.genericArgs.elementType, item) + }) + this.value = items + + return new Proxy(this, arrayProxyHandler()) as DynamicArrayImpl + } + + get bytes(): bytes { + return Bytes(this.uint8ArrayValue ?? this.encodeWithLength(this.items)) + } + + equals(other: this): boolean { + if (!(other instanceof DynamicArrayImpl) || JSON.stringify(this.typeInfo) !== JSON.stringify(other.typeInfo)) { + throw new internal.errors.CodeError(`Expected expression of type ${this.typeInfo.name}, got ${other.typeInfo.name}`) + } + return this.bytes.equals(other.bytes) + } + + get length(): uint64 { + return this.items.length + } + + get items(): TItem[] { + if (this.uint8ArrayValue) { + const [length, data] = readLength(this.uint8ArrayValue) + const childTypes = Array(length).fill(this.genericArgs.elementType) + this.value = decode(data, childTypes) as TItem[] + this.uint8ArrayValue = undefined + return this.value + } else if (this.value) { + this.uint8ArrayValue = undefined + return this.value + } + throw new internal.errors.CodeError('value is not set') + } + + setItem(index: number, value: TItem): void { + this.items[index] = value + } + + copy(): DynamicArrayImpl { + return DynamicArrayImpl.fromBytesImpl(this.bytes, JSON.stringify(this.typeInfo)) as DynamicArrayImpl + } + + push(...values: TItem[]) { + const items = this.items + items.push(...values) + } + + pop(): TItem { + const items = this.items + const popped = items.pop() + if (popped === undefined) internal.errors.avmError('The array is empty') + return popped + } + + static fromBytesImpl( + value: internal.primitives.StubBytesCompat | Uint8Array, + typeInfo: string | TypeInfo, + prefix: 'none' | 'log' = 'none', + ): DynamicArrayImpl { + let bytesValue = asBytesCls(value) + if (prefix === 'log') { + assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') + bytesValue = bytesValue.slice(4) + } + const result = new DynamicArrayImpl(typeInfo) + result.uint8ArrayValue = asUint8Array(bytesValue) + return result + } + + private encodeWithLength(items: TItem[]) { + return conactUint8Arrays(encodeLength(items.length).asUint8Array(), encode(items)) + } +} + +export class TupleImpl extends Tuple { + private value?: TTuple + private uint8ArrayValue?: Uint8Array + private typeInfo: TypeInfo + genericArgs: TypeInfo[] + + constructor(typeInfo: TypeInfo | string) + constructor(typeInfo: TypeInfo | string, ...items: TTuple) { + super(...items) + this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo + this.genericArgs = Object.values(this.typeInfo.genericArgs as Record) + + assert(areAllARC4Encoded(items), 'expected ARC4 type') + + items.forEach((item, index) => { + checkItemTypeName(this.genericArgs[index], item) + }) + this.value = items.length ? items : undefined + } + + get bytes(): bytes { + return Bytes(this.uint8ArrayValue ?? encode(this.items)) + } + + 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}`) + } + return this.bytes.equals(other.bytes) + } + + get length(): TTuple['length'] & uint64 { + return this.items.length + } + + get native(): TTuple { + return this.items + } + + at(index: TIndex): TTuple[TIndex] { + return this.items[index] + } + + private get items(): TTuple { + if (this.uint8ArrayValue) { + this.value = decode(this.uint8ArrayValue, this.genericArgs) as TTuple + this.uint8ArrayValue = undefined + return this.value + } else if (this.value) { + this.uint8ArrayValue = undefined + return this.value + } + throw new internal.errors.CodeError('value is not set') + } + + static fromBytesImpl( + value: internal.primitives.StubBytesCompat | Uint8Array, + typeInfo: string | TypeInfo, + prefix: 'none' | 'log' = 'none', + ): TupleImpl<[ARC4Encoded, ...ARC4Encoded[]]> { + let bytesValue = asBytesCls(value) + if (prefix === 'log') { + assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') + bytesValue = bytesValue.slice(4) + } + const result = new TupleImpl(typeInfo) + result.uint8ArrayValue = asUint8Array(bytesValue) + return result + } + + 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 (childType.name === 'Bool') { + 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 + } +} + +type StructConstraint = Record +export class StructImpl extends (Struct as DeliberateAny) { + private uint8ArrayValue?: Uint8Array + private typeInfo: TypeInfo + genericArgs: Record + + constructor(typeInfo: TypeInfo | string, value: T = {} as T) { + super(value) + this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo + this.genericArgs = this.typeInfo.genericArgs as Record + + Object.keys(this.genericArgs).forEach((key) => { + Object.defineProperty(this, key, { + value: value[key], + writable: true, + enumerable: true, + }) + }) + + return new Proxy(this, { + get(target, prop) { + const originalValue = Reflect.get(target, prop) + if (originalValue === undefined && target.uint8ArrayValue && Object.keys(target.genericArgs).includes(prop.toString())) { + return target.items[prop.toString()] + } + return originalValue + }, + set(target, prop, value) { + if (target.uint8ArrayValue && Object.keys(target.genericArgs).includes(prop.toString())) { + target.decodeAsProperties() + } + return Reflect.set(target, prop, value) + }, + }) + } + + get bytes(): bytes { + return Bytes(this.uint8ArrayValue ?? encode(Object.values(this.items))) + } + + get items(): T { + this.decodeAsProperties() + const result = {} as StructConstraint + Object.keys(this.genericArgs).forEach((key) => { + result[key] = (this as unknown as StructConstraint)[key] + }) + return result as T + } + + private decodeAsProperties() { + if (this.uint8ArrayValue) { + const values = decode(this.uint8ArrayValue, Object.values(this.genericArgs)) + Object.keys(this.genericArgs).forEach((key, index) => { + ;(this as unknown as StructConstraint)[key] = values[index] + }) + this.uint8ArrayValue = undefined + } + } + + static fromBytesImpl( + value: internal.primitives.StubBytesCompat | Uint8Array, + typeInfo: string | TypeInfo, + prefix: 'none' | 'log' = 'none', + ): StructImpl { + let bytesValue = asBytesCls(value) + if (prefix === 'log') { + assert(bytesValue.slice(0, 4).equals(ABI_RETURN_VALUE_LOG_PREFIX), 'ABI return prefix not found') + bytesValue = bytesValue.slice(4) + } + const result = new StructImpl(typeInfo) + result.uint8ArrayValue = asUint8Array(bytesValue) + return result + } +} + +export class DynamicBytesImpl extends DynamicBytes { + private typeInfo: TypeInfo + private value: DynamicArrayImpl + + constructor(typeInfo: TypeInfo | string, value?: bytes | string) { + super(value) + const uint8ArrayValue = conactUint8Arrays(encodeLength(value?.length ?? 0).asUint8Array(), asUint8Array(value ?? new Uint8Array())) + this.value = DynamicArrayImpl.fromBytesImpl(uint8ArrayValue, typeInfo) as DynamicArrayImpl + this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo + return new Proxy(this, arrayProxyHandler()) as DynamicBytesImpl + } + + get bytes(): bytes { + return this.value.bytes + } + + 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}`) + } + return this.bytes.equals(other.bytes) + } + + get length(): uint64 { + return this.value.length + } + + get native(): bytes { + return this.value.bytes.slice(ABI_LENGTH_SIZE) + } + + get items(): ByteImpl[] { + return this.value.items + } + + setItem(_index: number, _value: ByteImpl): void { + throw new internal.errors.CodeError('DynamicBytes is immutable') + } + + static fromBytesImpl( + value: internal.primitives.StubBytesCompat | Uint8Array, + typeInfo: string | TypeInfo, + prefix: 'none' | 'log' = 'none', + ): DynamicBytesImpl { + const dynamicArrayValue = DynamicArrayImpl.fromBytesImpl(value, typeInfo, prefix) as DynamicArrayImpl + const result = new DynamicBytesImpl(typeInfo) + result.value = dynamicArrayValue + return result + } +} + +export class StaticBytesImpl extends StaticBytes { + private value: StaticArrayImpl + private typeInfo: TypeInfo + + constructor(typeInfo: TypeInfo | string, value?: bytes | string) { + super(value) + const uint8ArrayValue = asUint8Array(value ?? new Uint8Array()) + this.value = StaticArrayImpl.fromBytesImpl(uint8ArrayValue, typeInfo) as StaticArrayImpl + this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo + return new Proxy(this, arrayProxyHandler()) as StaticBytesImpl + } + + get bytes(): bytes { + return this.value.bytes + } + + 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}`) + } + return this.bytes.equals(other.bytes) + } + + get length(): uint64 { + return this.value.length + } + + get native(): bytes { + return this.value.bytes + } + + get items(): ByteImpl[] { + return this.value.items + } + + setItem(_index: number, _value: ByteImpl): void { + throw new internal.errors.CodeError('StaticBytes is immutable') + } + + static fromBytesImpl( + value: internal.primitives.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 + return result + } + + static getMaxBytesLength(typeInfo: TypeInfo): number { + return StaticArrayImpl.getMaxBytesLength(typeInfo) + } +} + +const decode = (value: Uint8Array, childTypes: TypeInfo[]) => { + let i = 0 + let arrayIndex = 0 + const valuePartitions: Uint8Array[] = [] + const dynamicSegments: Array> = [] // Store the start and end of a dynamic element + + while (i < childTypes.length) { + const childType = childTypes[i] + if (holdsDynamicLengthContent(childType)) { + // Decode the size of the dynamic element + const dynamicIndex = uint8ArrayToNumber(value.slice(arrayIndex, arrayIndex + ABI_LENGTH_SIZE)) + if (dynamicSegments.length) { + dynamicSegments.at(-1)![1] = dynamicIndex + } + // Since we do not know where the current dynamic element ends, + // put a placeholder and update later + dynamicSegments.push([dynamicIndex, -1]) + valuePartitions.push(new Uint8Array()) + arrayIndex += ABI_LENGTH_SIZE + } else if (childType.name === 'Bool') { + 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"') + } + after = Math.min(7, after) + const bits = uint8ArrayToNumber(value.slice(arrayIndex, arrayIndex + 1)) + Array(after + 1) + .fill(0) + .forEach((_, j) => { + const mask = 128 >> j + valuePartitions.push( + mask & bits ? encodingUtil.bigIntToUint8Array(TRUE_BIGINT_VALUE) : encodingUtil.bigIntToUint8Array(FALSE_BIGINT_VALUE), + ) + }) + i += after + arrayIndex += 1 + } else { + const currLen = getMaxLengthOfStaticContentType(childType) + valuePartitions.push(value.slice(arrayIndex, arrayIndex + currLen)) + arrayIndex += currLen + } + + if (arrayIndex >= value.length && i != childTypes.length - 1) { + throw new internal.errors.CodeError('input string is not long enough to be decoded') + } + i += 1 + } + + if (dynamicSegments.length > 0) { + dynamicSegments.at(-1)![1] = value.length + arrayIndex = value.length + } + if (arrayIndex < value.length) { + throw new internal.errors.CodeError('input string was not fully consumed') + } + + // Check dynamic element partitions + let segmentIndex = 0 + childTypes.forEach((childType, index) => { + if (holdsDynamicLengthContent(childType)) { + const [segmentStart, segmentEnd] = dynamicSegments[segmentIndex] + valuePartitions[index] = value.slice(segmentStart, segmentEnd) + segmentIndex += 1 + } + }) + + const values: ARC4Encoded[] = [] + childTypes.forEach((childType, index) => { + values.push(getArc4Encoder(childType)(valuePartitions[index], childType)) + }) + return values +} + +const findBoolTypes = (values: TypeInfo[], index: number, delta: number): number => { + // Helper function to find consecutive booleans from current index in a tuple. + let until = 0 + const length = values.length + while (true) { + const curr = index + delta * until + if (values[curr].name === 'Bool') { + if ((curr != length - 1 && delta > 0) || (curr > 0 && delta < 0)) { + until += 1 + } else { + break + } + } else { + until -= 1 + break + } + } + return until +} + +const getMaxLengthOfStaticContentType = (type: TypeInfo): number => { + switch (trimGenericTypeName(type.name)) { + case 'Address': + return AddressImpl.getMaxBytesLength(type) + case 'Byte': + return ByteImpl.getMaxBitsLength(type) / BITS_IN_BYTE + case 'UintN': + return UintNImpl.getMaxBitsLength(type) / BITS_IN_BYTE + case 'UFixedNxM': + return UFixedNxMImpl.getMaxBitsLength(type) / BITS_IN_BYTE + case 'StaticArray': + return StaticArrayImpl.getMaxBytesLength(type) + case 'StaticBytes': + return StaticBytesImpl.getMaxBytesLength(type) + case 'Tuple': + return TupleImpl.getMaxBytesLength(type) + } + throw new internal.errors.CodeError(`unsupported type ${type.name}`) +} + +const encode = (values: ARC4Encoded[]) => { + const length = values.length + const heads = [] + const tails = [] + const dynamicLengthTypeIndex = [] + let i = 0 + const valuesLengthBytes = values instanceof DynamicArray ? encodeLength(length).asUint8Array() : new Uint8Array() + while (i < length) { + const value = values[i] + assert(value instanceof ARC4Encoded, `expected ARC4 type ${value.constructor.name}`) + dynamicLengthTypeIndex.push(isDynamicLengthType(value)) + if (dynamicLengthTypeIndex.at(-1)) { + heads.push(asUint8Array(Bytes.fromHex('0000'))) + tails.push(asUint8Array(value.bytes)) + } else { + if (value instanceof Bool) { + 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"') + } + after = Math.min(7, after) + const consecutiveBools = values.slice(i, i + after + 1) as Bool[] + const compressedNumber = compressMultipleBool(consecutiveBools) + heads.push(new Uint8Array([compressedNumber])) + i += after + } else { + heads.push(asUint8Array(value.bytes)) + } + tails.push(new Uint8Array()) + } + i += 1 + } + + // Adjust heads for dynamic types + let headLength = 0 + heads.forEach((head) => { + // If the element is not a placeholder, append the length of the element + headLength += head.length + }) + + // Correctly encode dynamic types and replace placeholder + let tailCurrLength = 0 + for (let i = 0; i < heads.length; i++) { + if (dynamicLengthTypeIndex[i]) { + const headValue = headLength + tailCurrLength + heads[i] = asUint8Array(encodeLength(headValue)) + } + tailCurrLength += tails[i].length + } + + return conactUint8Arrays(valuesLengthBytes, ...heads, ...tails) +} + +const findBool = (values: ARC4Encoded[], index: number, delta: number) => { + let until = 0 + const length = values.length + while (true) { + const curr = index + delta * until + if (values[curr] instanceof Bool) { + if ((curr !== length - 1 && delta > 0) || (curr > 0 && delta < 0)) { + until += 1 + } else { + break + } + } else { + until -= 1 + break + } + } + return until +} + +const compressMultipleBool = (values: Bool[]): number => { + let result = 0 + if (values.length > 8) { + throw new Error('length of list should not be greater than 8') + } + for (let i = 0; i < values.length; i++) { + const value = values[i] + if (value.native) { + result |= 1 << (7 - i) + } + } + return result +} + +const trimGenericTypeName = (typeName: string) => typeName.replace(/<.*>/, '') + +const isDynamicLengthType = (value: ARC4Encoded) => + value instanceof StrImpl || + (value instanceof StaticArrayImpl && holdsDynamicLengthContent(value)) || + (value instanceof TupleImpl && value.genericArgs.some(holdsDynamicLengthContent)) || + (value instanceof StructImpl && Object.values(value.genericArgs).some(holdsDynamicLengthContent)) || + value instanceof DynamicArrayImpl || + value instanceof DynamicBytesImpl + +const holdsDynamicLengthContent = (value: StaticArrayImpl | DynamicArrayImpl | TypeInfo): boolean => { + const itemTypeName = trimGenericTypeName( + value instanceof StaticArrayImpl || value instanceof DynamicArrayImpl ? value.genericArgs.elementType.name : value.name, + ) + return ( + itemTypeName === 'Str' || + itemTypeName === 'DynamicArray' || + itemTypeName === 'DynamicBytes' || + (itemTypeName === 'StaticArray' && + holdsDynamicLengthContent(((value as StaticArrayImpl).genericArgs as StaticArrayGenericArgs).elementType)) || + ((itemTypeName === 'Tuple' || itemTypeName === 'Struct') && + Object.values(value.genericArgs as Record).some(holdsDynamicLengthContent)) + ) +} + export function interpretAsArc4Impl( typeInfoString: string, bytes: internal.primitives.StubBytesCompat, @@ -245,11 +1077,18 @@ export function interpretAsArc4Impl( } export const arc4Encoders: Record> = { + Address: AddressImpl.fromBytesImpl, Bool: BoolImpl.fromBytesImpl, Byte: ByteImpl.fromBytesImpl, Str: StrImpl.fromBytesImpl, 'UintN<.*>': UintNImpl.fromBytesImpl, 'UFixedNxM<.*>': UFixedNxMImpl.fromBytesImpl, + 'StaticArray<.*>': StaticArrayImpl.fromBytesImpl, + 'DynamicArray<.*>': DynamicArrayImpl.fromBytesImpl, + Tuple: TupleImpl.fromBytesImpl, + Struct: StructImpl.fromBytesImpl, + DynamicBytes: DynamicBytesImpl.fromBytesImpl, + 'StaticBytes<.*>': StaticBytesImpl.fromBytesImpl, } export const getArc4Encoder = (typeInfo: TypeInfo, encoders?: Record>): fromBytes => { const encoder = Object.entries(encoders ?? arc4Encoders).find(([k, _]) => new RegExp(`^${k}$`, 'i').test(typeInfo.name))?.[1] diff --git a/src/util.ts b/src/util.ts index c2296a5..0cd42eb 100644 --- a/src/util.ts +++ b/src/util.ts @@ -192,3 +192,7 @@ export const conactUint8Arrays = (...values: Uint8Array[]): Uint8Array => { } return result } + +export const uint8ArrayToNumber = (value: Uint8Array): number => { + return value.reduce((acc, x) => acc * 256 + x, 0) +} diff --git a/tests/arc4/address.spec.ts b/tests/arc4/address.spec.ts new file mode 100644 index 0000000..905504b --- /dev/null +++ b/tests/arc4/address.spec.ts @@ -0,0 +1,83 @@ +import { Account, Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { Address, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' +import { ABIType, encodeAddress } from 'algosdk' +import { afterEach, describe, expect, test } from 'vitest' +import { ABI_RETURN_VALUE_LOG_PREFIX } from '../../src/constants' +import { asUint8Array } from '../util' + +const abiAddressType = ABIType.from('address') +const testData = [ + Bytes.fromHex('00'.repeat(32)), + Bytes.fromHex('01'.repeat(32)), + Bytes.fromHex('ff'.repeat(32)), + Bytes.fromHex(`${'00'.repeat(31)}ff`), +] + +describe('arc4.Address', async () => { + const ctx = new TestExecutionContext() + afterEach(async () => { + ctx.reset() + }) + + test.each(testData)('create address from bytes', async (value) => { + const sdkResult = abiAddressType.encode(asUint8Array(value)) + const result = new Address(value) + expect(result.bytes).toEqual(sdkResult) + }) + test.each(testData)('create address from str', async (value) => { + const stringValue = encodeAddress(asUint8Array(value)) + const sdkResult = abiAddressType.encode(stringValue) + const result = new Address(stringValue) + expect(result.bytes).toEqual(sdkResult) + }) + test.each(testData)('create address from Account', async (value) => { + const accountValue = Account(value) + const sdkResult = abiAddressType.encode(asUint8Array(accountValue.bytes)) + const result = new Address(accountValue) + expect(result.bytes).toEqual(sdkResult) + }) + + test.each(testData)('get item from address created from bytes', async (value) => { + const uint8ArrayValue = asUint8Array(value) + const result = new Address(value) + let i = 0 + for (const entry of result) { + expect(entry.native).toEqual(uint8ArrayValue[i++]) + } + expect(result.length).toEqual(uint8ArrayValue.length) + }) + test.each(testData)('get item from address created from str', async (value) => { + const uint8ArrayValue = asUint8Array(value) + const stringValue = encodeAddress(uint8ArrayValue) + const result = new Address(stringValue) + let i = 0 + for (const entry of result) { + expect(entry.native).toEqual(uint8ArrayValue[i++]) + } + expect(result.length).toEqual(uint8ArrayValue.length) + }) + test.each(testData)('get item from address created from Account', async (value) => { + const uint8ArrayValue = asUint8Array(value) + const accountValue = Account(value) + const result = new Address(accountValue) + let i = 0 + for (const entry of result) { + expect(entry.native).toEqual(uint8ArrayValue[i++]) + } + expect(result.length).toEqual(uint8ArrayValue.length) + }) + + test.each(testData)('fromBytes method', async (value) => { + const sdkResult = abiAddressType.encode(asUint8Array(value)) + const result = interpretAsArc4
(value) + expect(result.bytes).toEqual(sdkResult) + }) + + test.each(testData)('fromLog method', async (value) => { + const sdkResult = abiAddressType.encode(asUint8Array(value)) + const paddedValue = Bytes([...asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX), ...asUint8Array(value)]) + const result = interpretAsArc4
(paddedValue, 'log') + expect(result.bytes).toEqual(sdkResult) + }) +}) diff --git a/tests/arc4/dynamic-array.spec.ts b/tests/arc4/dynamic-array.spec.ts new file mode 100644 index 0000000..836a83e --- /dev/null +++ b/tests/arc4/dynamic-array.spec.ts @@ -0,0 +1,625 @@ +import { Bytes, internal } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { + Address, + Bool, + DynamicArray, + interpretAsArc4, + StaticArray, + Str, + Struct, + Tuple, + UFixedNxM, + UintN, +} from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { ABIType } from 'algosdk' +import { afterEach, describe, expect, it, test } from 'vitest' +import { AccountCls } from '../../src/impl/account' +import { DeliberateAny } from '../../src/typescript-helpers' +import { asBytes, asUint8Array } from '../../src/util' + +const addressDynamicArray = { + abiType: ABIType.from('address[]'), + nativeValues() { + return [ + asUint8Array(Bytes.fromHex('00'.repeat(32))), + asUint8Array(Bytes.fromHex('01'.repeat(32))), + asUint8Array(Bytes.fromHex('ff'.repeat(32))), + asUint8Array(Bytes.fromHex(`${'00'.repeat(31)}ff`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(30)}${'ff'.repeat(2)}`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(29)}${'ff'.repeat(3)}`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(28)}${'ff'.repeat(4)}`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(27)}${'ff'.repeat(5)}`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(26)}${'ff'.repeat(6)}`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(25)}${'ff'.repeat(7)}`)), + ] + }, + abiValues() { + return this.nativeValues().map((v) => new Address(Bytes(v))) + }, + array(isEmpty = false) { + return isEmpty ? new DynamicArray
() : new DynamicArray
(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>(asBytes(value)) + }, +} +const boolDynamicArray = { + abiType: ABIType.from('bool[]'), + nativeValues() { + return [true, true, false, true, false, true, true, false, true, false] + }, + abiValues() { + return this.nativeValues().map((v) => new Bool(v)) + }, + array(isEmpty = false) { + return isEmpty ? new DynamicArray() : new DynamicArray(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>(asBytes(value)) + }, +} +const uint256DynamicArray = { + abiType: ABIType.from('uint256[]'), + nativeValues() { + return [0n, 1n, 2n, 3n, 2n ** 8n, 2n ** 16n, 2n ** 32n, 2n ** 64n, 2n ** 128n, 2n ** 256n - 1n] + }, + abiValues() { + return this.nativeValues().map((v) => new UintN<256>(v)) + }, + array(isEmpty = false) { + return isEmpty ? new DynamicArray>() : new DynamicArray>(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>>(asBytes(value)) + }, +} +const ufixednxmDynamicArray = { + abiType: ABIType.from('ufixed256x16[]'), + nativeValues() { + return this.abiValues().map((v) => v.native.valueOf()) + }, + abiValues() { + return [ + new UFixedNxM<256, 16>('0.0'), + new UFixedNxM<256, 16>('1.0'), + new UFixedNxM<256, 16>('2.0'), + new UFixedNxM<256, 16>('3.0'), + new UFixedNxM<256, 16>('255.0'), + new UFixedNxM<256, 16>('65536.0'), + new UFixedNxM<256, 16>('4294967295.0'), + new UFixedNxM<256, 16>('1844.6744073709551616'), + new UFixedNxM<256, 16>('340282366920938463463374.607431768211456'), + new UFixedNxM<256, 16>('11579208923731619542357098500868790785326998466564056403945758.4007913129639935'), + ] + }, + array(isEmpty = false) { + return isEmpty ? new DynamicArray>() : new DynamicArray>(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>>(asBytes(value)) + }, +} +const stringDynamicArray = { + abiType: ABIType.from('string[]'), + nativeValues() { + return [ + '', + '1', + 'hello', + 'World', + (2 ** 8).toString(), + (2 ** 16).toString(), + (2 ** 32).toString(), + (2 ** 64).toString(), + (2 ** 128).toString(), + (2 ** 256).toString(), + ] + }, + abiValues() { + return this.nativeValues().map((v) => new Str(v)) + }, + array(isEmpty = false) { + return isEmpty ? new DynamicArray() : new DynamicArray(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>(asBytes(value)) + }, +} +const boolDynamicArrayOfArray = { + abiType: ABIType.from('bool[][]'), + nativeValues() { + return [boolDynamicArray.nativeValues(), boolDynamicArray.nativeValues().reverse()] + }, + abiValues() { + return this.nativeValues().map((a) => new DynamicArray(...a.map((v) => new Bool(v)))) + }, + array(isEmpty = false) { + return isEmpty + ? new DynamicArray>() + : new DynamicArray>(...this.abiValues().map((a) => new DynamicArray(...a))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>>(asBytes(value)) + }, +} +const addressDynamicArrayOfArray = { + abiType: ABIType.from('address[][]'), + nativeValues() { + return [addressDynamicArray.nativeValues(), addressDynamicArray.nativeValues().reverse()] + }, + abiValues() { + return this.nativeValues().map((a) => new DynamicArray
(...a.map((v) => new Address(Bytes(v))))) + }, + array(isEmpty = false) { + return isEmpty + ? new DynamicArray>() + : new DynamicArray>(...this.abiValues().map((a) => new DynamicArray
(...a))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>>(asBytes(value)) + }, +} +const uint256DynamicArrayOfArray = { + abiType: ABIType.from('uint256[][]'), + nativeValues() { + return [uint256DynamicArray.nativeValues(), uint256DynamicArray.nativeValues().reverse()] + }, + abiValues() { + return this.nativeValues().map((a) => new DynamicArray>(...a.map((v) => new UintN<256>(v)))) + }, + array(isEmpty = false) { + return isEmpty + ? new DynamicArray>>() + : new DynamicArray>>(...this.abiValues().map((a) => new DynamicArray>(...a))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>>>(asBytes(value)) + }, +} +const uint256DynamicArrayOfStaticArray = { + abiType: ABIType.from('uint256[10][]'), + nativeValues() { + return [uint256DynamicArray.nativeValues(), uint256DynamicArray.nativeValues().reverse()] + }, + abiValues() { + return this.nativeValues().map((a) => new StaticArray, 10>(...a.map((v) => new UintN<256>(v)))) + }, + array(isEmpty = false) { + return isEmpty + ? new DynamicArray, 10>>() + : new DynamicArray, 10>>(...this.abiValues().map((a) => new StaticArray, 10>(...a))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, 10>>>(asBytes(value)) + }, +} +const stringDynamicArrayOfArray = { + abiType: ABIType.from('string[][]'), + nativeValues() { + return [stringDynamicArray.nativeValues(), stringDynamicArray.nativeValues().reverse()] + }, + abiValues() { + return this.nativeValues().map((a) => new DynamicArray(...a.map((v) => new Str(v)))) + }, + array(isEmpty = false) { + return isEmpty + ? new DynamicArray>() + : new DynamicArray>(...this.abiValues().map((a) => new DynamicArray(...a))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>>(asBytes(value)) + }, +} +const stringDynamicArrayOfArrayOfArray = { + abiType: ABIType.from('string[][][]'), + nativeValues() { + return [ + [stringDynamicArray.nativeValues(), stringDynamicArray.nativeValues().reverse(), stringDynamicArray.nativeValues()], + [stringDynamicArray.nativeValues().reverse(), stringDynamicArray.nativeValues(), stringDynamicArray.nativeValues().reverse()], + ] + }, + abiValues() { + return this.nativeValues().map( + (x) => new DynamicArray>(...x.map((y) => new DynamicArray(...y.map((v) => new Str(v))))), + ) + }, + array(isEmpty = false) { + return isEmpty + ? new DynamicArray>>() + : new DynamicArray>>(...this.abiValues().map((x) => new DynamicArray>(...x))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>>>(asBytes(value)) + }, +} +const tupleDynamicArray = { + abiType: ABIType.from('(string[],(string[],string,uint256,address),bool,uint256[3])[]'), + nativeValues() { + return Array(2).fill([ + stringDynamicArray.nativeValues().slice(0, 2), + [ + stringDynamicArray.nativeValues().slice(6, 8), + stringDynamicArray.nativeValues()[9], + uint256DynamicArray.nativeValues()[4], + addressDynamicArray.nativeValues()[5], + ], + boolDynamicArray.nativeValues()[3], + uint256DynamicArray.nativeValues().slice(4, 7), + ]) + }, + abiValues() { + return Array(2).fill( + new Tuple( + ...[ + new DynamicArray(...stringDynamicArray.abiValues().slice(0, 2)), + new Tuple<[DynamicArray, Str, UintN<256>, Address]>( + new DynamicArray(...stringDynamicArray.abiValues().slice(6, 8)), + stringDynamicArray.abiValues()[9], + uint256DynamicArray.abiValues()[4], + addressDynamicArray.abiValues()[5], + ), + boolDynamicArray.abiValues()[3], + new StaticArray, 3>(...uint256DynamicArray.abiValues().slice(4, 7)), + ], + ), + ) + }, + array(isEmpty = false) { + return isEmpty + ? new DynamicArray< + Tuple<[DynamicArray, Tuple<[DynamicArray, Str, UintN<256>, Address]>, Bool, StaticArray, 3>]> + >() + : new DynamicArray< + Tuple<[DynamicArray, Tuple<[DynamicArray, Str, UintN<256>, Address]>, Bool, StaticArray, 3>]> + >(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4< + DynamicArray, Tuple<[DynamicArray, Str, UintN<256>, Address]>, Bool, StaticArray, 3>]>> + >(asBytes(value)) + }, +} +class Swapped extends Struct<{ + b: UintN<256> + c: Bool + d: Str + a: Tuple<[DynamicArray, DynamicArray, Str, UintN<256>, Bool, StaticArray, 3>]> +}> {} +const structDynamicArray = { + abiType: ABIType.from('(uint256,bool,string,(string[],string[],string,uint256,bool,uint256[3]))[]'), + nativeValues() { + return Array(2).fill([ + uint256DynamicArray.nativeValues()[0], + boolDynamicArray.nativeValues()[1], + stringDynamicArray.nativeValues()[2], + [ + [stringDynamicArray.nativeValues()[3], stringDynamicArray.nativeValues()[4]], + [stringDynamicArray.nativeValues()[5], stringDynamicArray.nativeValues()[6]], + stringDynamicArray.nativeValues()[7], + uint256DynamicArray.nativeValues()[1], + boolDynamicArray.nativeValues()[2], + [uint256DynamicArray.nativeValues()[2], uint256DynamicArray.nativeValues()[3], uint256DynamicArray.nativeValues()[4]], + ], + ]) + }, + abiValues() { + return Array(2).fill( + new Swapped({ + b: uint256DynamicArray.abiValues()[0], + c: boolDynamicArray.abiValues()[1], + d: stringDynamicArray.abiValues()[2], + a: new Tuple( + new DynamicArray(stringDynamicArray.abiValues()[3], stringDynamicArray.abiValues()[4]), + new DynamicArray(stringDynamicArray.abiValues()[5], stringDynamicArray.abiValues()[6]), + stringDynamicArray.abiValues()[7], + uint256DynamicArray.abiValues()[1], + boolDynamicArray.abiValues()[2], + new StaticArray, 3>( + uint256DynamicArray.abiValues()[2], + uint256DynamicArray.abiValues()[3], + uint256DynamicArray.abiValues()[4], + ), + ), + }), + ) + }, + array(isEmpty = false) { + return isEmpty ? new DynamicArray() : new DynamicArray(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>(asBytes(value)) + }, +} + +describe('arc4.DynamicArray', async () => { + const ctx = new TestExecutionContext() + afterEach(async () => { + ctx.reset() + }) + + test.each([ + addressDynamicArray, + boolDynamicArray, + uint256DynamicArray, + ufixednxmDynamicArray, + stringDynamicArray, + addressDynamicArrayOfArray, + boolDynamicArrayOfArray, + uint256DynamicArrayOfArray, + uint256DynamicArrayOfStaticArray, + stringDynamicArrayOfArray, + stringDynamicArrayOfArrayOfArray, + tupleDynamicArray, + structDynamicArray, + ])('should be able to get bytes representation', async (data) => { + const sdkResult = data.abiType.encode(data.nativeValues()) + const result = data.array().bytes + expect(result).toEqual(sdkResult) + }) + + test.each([ + addressDynamicArray, + boolDynamicArray, + uint256DynamicArray, + ufixednxmDynamicArray, + stringDynamicArray, + addressDynamicArrayOfArray, + boolDynamicArrayOfArray, + uint256DynamicArrayOfArray, + uint256DynamicArrayOfStaticArray, + stringDynamicArrayOfArray, + stringDynamicArrayOfArrayOfArray, + tupleDynamicArray, + structDynamicArray, + ])('copy dynamic array', async (data) => { + const sdkResult = data.abiType.encode(data.nativeValues()) + const original = data.array() + const copy = original.copy() + const result = copy.bytes + expect(copy.length).toEqual(original.length) + expect(result).toEqual(sdkResult) + }) + + test.each([ + addressDynamicArray, + boolDynamicArray, + uint256DynamicArray, + ufixednxmDynamicArray, + stringDynamicArray, + addressDynamicArrayOfArray, + boolDynamicArrayOfArray, + uint256DynamicArrayOfArray, + uint256DynamicArrayOfStaticArray, + stringDynamicArrayOfArray, + stringDynamicArrayOfArrayOfArray, + tupleDynamicArray, + structDynamicArray, + ])('get item from dynamic array', async (data) => { + const dynamicArray = data.array() + const nativeValues = data.nativeValues() + for (let i = 0; i < dynamicArray.length; i++) { + compareARC4AndABIValue(dynamicArray[i], nativeValues[i]) + } + expect(dynamicArray.length).toEqual(nativeValues.length) + }) + + test.each([ + addressDynamicArray, + boolDynamicArray, + uint256DynamicArray, + ufixednxmDynamicArray, + stringDynamicArray, + addressDynamicArrayOfArray, + boolDynamicArrayOfArray, + uint256DynamicArrayOfArray, + uint256DynamicArrayOfStaticArray, + stringDynamicArrayOfArray, + stringDynamicArrayOfArrayOfArray, + tupleDynamicArray, + structDynamicArray, + ])('set item in dynamic array', async (data) => { + const nativeValues = data.nativeValues() + const nativeValuesCopy = [...nativeValues] + const nativeTemp = nativeValuesCopy.at(-1)! + nativeValuesCopy[nativeValuesCopy.length - 1] = nativeValuesCopy[0] + nativeValuesCopy[0] = nativeTemp + + const dynamicArray = data.array() + const dynamicArrayCopy = dynamicArray.copy() + const arrayTemp = dynamicArrayCopy.at(-1) + dynamicArrayCopy[dynamicArrayCopy.length - 1] = dynamicArrayCopy[0] + dynamicArrayCopy[0] = arrayTemp + + const sdkResult = data.abiType.encode(nativeValuesCopy) + const result = dynamicArrayCopy.bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + + test.each([ + addressDynamicArray, + boolDynamicArray, + uint256DynamicArray, + ufixednxmDynamicArray, + stringDynamicArray, + addressDynamicArrayOfArray, + boolDynamicArrayOfArray, + uint256DynamicArrayOfArray, + uint256DynamicArrayOfStaticArray, + stringDynamicArrayOfArray, + stringDynamicArrayOfArrayOfArray, + tupleDynamicArray, + structDynamicArray, + ])('create dynamic array from bytes', async (data) => { + const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const result = data.create(Bytes(sdkEncodedBytes)) + const nativeValues = data.nativeValues() + for (let i = 0; i < result.length; i++) { + compareARC4AndABIValue(result[i], nativeValues[i]) + } + }) + + test.each([ + addressDynamicArray, + boolDynamicArray, + uint256DynamicArray, + ufixednxmDynamicArray, + stringDynamicArray, + addressDynamicArrayOfArray, + boolDynamicArrayOfArray, + uint256DynamicArrayOfArray, + uint256DynamicArrayOfStaticArray, + stringDynamicArrayOfArray, + stringDynamicArrayOfArrayOfArray, + tupleDynamicArray, + structDynamicArray, + ])('push item to dynamic array', async (data) => { + const nativeValues = data.nativeValues() + const nativeValuesCopy = [...nativeValues] + nativeValuesCopy.push(nativeValues.at(-1)!) + nativeValuesCopy.push(nativeValues[0]) + + const dynamicArray = data.array() + const dynamicArrayCopy = dynamicArray.copy() + dynamicArrayCopy.push(dynamicArray.at(-1) as never, dynamicArray[0] as never) + + const sdkResult = data.abiType.encode(nativeValuesCopy) + const result = dynamicArrayCopy.bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + + test.each([ + addressDynamicArray, + boolDynamicArray, + uint256DynamicArray, + ufixednxmDynamicArray, + stringDynamicArray, + addressDynamicArrayOfArray, + boolDynamicArrayOfArray, + uint256DynamicArrayOfArray, + uint256DynamicArrayOfStaticArray, + stringDynamicArrayOfArray, + stringDynamicArrayOfArrayOfArray, + tupleDynamicArray, + structDynamicArray, + ])('push item to empty dynamic array', async (data) => { + const nativeValues = data.nativeValues() + const sdkResult = data.abiType.encode(nativeValues) + + const emptyArray = data.array(true) + data.abiValues().forEach((v) => emptyArray.push(v as never)) + expect(emptyArray.length).toEqual(nativeValues.length) + expect(emptyArray.bytes).toEqual(sdkResult) + }) + + test.each([ + addressDynamicArray, + boolDynamicArray, + uint256DynamicArray, + ufixednxmDynamicArray, + stringDynamicArray, + addressDynamicArrayOfArray, + boolDynamicArrayOfArray, + uint256DynamicArrayOfArray, + uint256DynamicArrayOfStaticArray, + stringDynamicArrayOfArray, + stringDynamicArrayOfArrayOfArray, + tupleDynamicArray, + structDynamicArray, + ])('push item to empty dynamic array created from bytes', async (data) => { + const nativeValues = data.nativeValues() + const sdkResult = data.abiType.encode(nativeValues) + + const emptyArray = data.create(Bytes(data.abiType.encode([]))) + data.abiValues().forEach((v) => emptyArray.push(v as never)) + expect(emptyArray.length).toEqual(nativeValues.length) + expect(emptyArray.bytes).toEqual(sdkResult) + }) + + test.each([ + addressDynamicArray, + boolDynamicArray, + uint256DynamicArray, + ufixednxmDynamicArray, + stringDynamicArray, + addressDynamicArrayOfArray, + boolDynamicArrayOfArray, + uint256DynamicArrayOfArray, + uint256DynamicArrayOfStaticArray, + stringDynamicArrayOfArray, + stringDynamicArrayOfArrayOfArray, + tupleDynamicArray, + structDynamicArray, + ])('pop item from dynamic array', async (data) => { + const nativeValues = data.nativeValues() + const nativeValuesCopy = [...nativeValues] + const nativeValue1 = nativeValuesCopy.pop() + const nativeValue2 = nativeValuesCopy.pop() + + const dynamicArray = data.array() + const dynamicArrayCopy = dynamicArray.copy() + const value1 = dynamicArrayCopy.pop() + const value2 = dynamicArrayCopy.pop() + + compareARC4AndABIValue(value1, nativeValue1) + compareARC4AndABIValue(value2, nativeValue2) + + const sdkResult = data.abiType.encode(nativeValuesCopy) + const result = dynamicArrayCopy.bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + + it('set item in nested dynamic array', async () => { + const data = stringDynamicArrayOfArrayOfArray + const nativeValues = data.nativeValues() + nativeValues[0][0][0] = 'new value' + + const dynamicArray = data.array() + dynamicArray[0][0][0] = new Str('new value') + + const sdkResult = data.abiType.encode(nativeValues) + const result = dynamicArray.bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + + it('set item in nested dynamic array created from bytes', async () => { + const data = stringDynamicArrayOfArrayOfArray + const nativeValues = data.nativeValues() + nativeValues[0][0][0] = 'new value' + + const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const dynamicArray = data.create(Bytes(sdkEncodedBytes)) + dynamicArray[0][0][0] = new Str('new value') + + const sdkResult = data.abiType.encode(nativeValues) + const result = dynamicArray.bytes + expect(result).toEqual(Bytes(sdkResult)) + }) +}) + +const compareARC4AndABIValue = (arc4Value: DeliberateAny, nativeValue: DeliberateAny) => { + if (arc4Value instanceof DynamicArray || arc4Value instanceof StaticArray) { + for (let i = 0; i < arc4Value.length; i++) { + compareARC4AndABIValue(arc4Value[i], nativeValue[i]) + } + } else if (arc4Value instanceof Tuple) { + const tupleValues = arc4Value.native + for (let i = 0; i < arc4Value.length; i++) { + compareARC4AndABIValue(tupleValues[i], nativeValue[i]) + } + } else if (arc4Value instanceof Struct) { + const structValues = Object.values(arc4Value.items) + for (let i = 0; i < structValues.length; i++) { + compareARC4AndABIValue(structValues[i], nativeValue[i]) + } + } else if (arc4Value.native !== undefined) { + if (arc4Value.native instanceof AccountCls) { + expect(arc4Value.native.bytes).toEqual(nativeValue) + } else { + expect(arc4Value.native).toEqual(nativeValue) + } + } else { + expect(arc4Value.bytes).toEqual(encodingUtil.bigIntToUint8Array(arc4Value, arc4Value.bytes.length)) + } +} diff --git a/tests/arc4/dynamic-bytes.spec.ts b/tests/arc4/dynamic-bytes.spec.ts new file mode 100644 index 0000000..ee1bfc2 --- /dev/null +++ b/tests/arc4/dynamic-bytes.spec.ts @@ -0,0 +1,51 @@ +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { DynamicBytes, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { ABIType } from 'algosdk' +import { describe, expect, test } from 'vitest' + +const abiType = ABIType.from('byte[]') +const testData = [ + { + nativeValue() { + return [0, 1, 8, 16, 32, 64, 128, 255, 20, 30, 40, 50, 111] + }, + dynamicBytes() { + return new DynamicBytes(Bytes(this.nativeValue())) + }, + }, + { + nativeValue() { + return encodingUtil.utf8ToUint8Array('01ff99aa'.repeat(8)) + }, + dynamicBytes() { + return new DynamicBytes('01ff99aa'.repeat(8)) + }, + }, +] + +describe('arc4.DynamicBytes', async () => { + test.each(testData)('should be able to get bytes representation', async (data) => { + const sdkResult = abiType.encode(data.nativeValue()) + const result = 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() + for (let i = 0; i < dynamicArray.length; i++) { + expect(dynamicArray[i].native).toEqual(nativeValue[i]) + } + expect(dynamicArray.length).toEqual(nativeValue.length) + }) + + test.each(testData)('create dynamic bytes from bytes', async (data) => { + const nativeValue = data.nativeValue() + const sdkEncodedBytes = abiType.encode(nativeValue) + const result = interpretAsArc4(Bytes(sdkEncodedBytes)) + for (let i = 0; i < result.length; i++) { + expect(result[i].native).toEqual(nativeValue[i]) + } + }) +}) diff --git a/tests/arc4/static-array.spec.ts b/tests/arc4/static-array.spec.ts new file mode 100644 index 0000000..85a19b4 --- /dev/null +++ b/tests/arc4/static-array.spec.ts @@ -0,0 +1,559 @@ +import { Bytes, internal } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { + Address, + Bool, + DynamicArray, + interpretAsArc4, + StaticArray, + Str, + Struct, + Tuple, + UFixedNxM, + UintN, +} from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { ABIType } from 'algosdk' +import { afterEach, describe, expect, it, test } from 'vitest' +import { AccountCls } from '../../src/impl/account' +import { DeliberateAny } from '../../src/typescript-helpers' +import { asBytes, asUint8Array } from '../../src/util' + +const addressStaticArray = { + abiType: ABIType.from('address[10]'), + nativeValues() { + return [ + asUint8Array(Bytes.fromHex('00'.repeat(32))), + asUint8Array(Bytes.fromHex('01'.repeat(32))), + asUint8Array(Bytes.fromHex('ff'.repeat(32))), + asUint8Array(Bytes.fromHex(`${'00'.repeat(31)}ff`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(30)}${'ff'.repeat(2)}`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(29)}${'ff'.repeat(3)}`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(28)}${'ff'.repeat(4)}`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(27)}${'ff'.repeat(5)}`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(26)}${'ff'.repeat(6)}`)), + asUint8Array(Bytes.fromHex(`${'00'.repeat(25)}${'ff'.repeat(7)}`)), + ] + }, + abiValues() { + return this.nativeValues().map((v) => new Address(Bytes(v))) + }, + array() { + return new StaticArray(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>(asBytes(value)) + }, +} +const boolStaticArray = { + abiType: ABIType.from('bool[10]'), + nativeValues() { + return [true, true, false, true, false, true, true, false, true, false] + }, + abiValues() { + return this.nativeValues().map((v) => new Bool(v)) + }, + array() { + return new StaticArray(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>(asBytes(value)) + }, +} +const uint256StaticArray = { + abiType: ABIType.from('uint256[10]'), + nativeValues() { + return [0n, 1n, 2n, 3n, 2n ** 8n, 2n ** 16n, 2n ** 32n, 2n ** 64n, 2n ** 128n, 2n ** 256n - 1n] + }, + abiValues() { + return this.nativeValues().map((v) => new UintN<256>(v)) + }, + array() { + return new StaticArray, 10>(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, 10>>(asBytes(value)) + }, +} +const ufixednxmStaticArray = { + abiType: ABIType.from('ufixed256x16[10]'), + nativeValues() { + return this.abiValues().map((v) => v.native.valueOf()) + }, + abiValues() { + return [ + new UFixedNxM<256, 16>('0.0'), + new UFixedNxM<256, 16>('1.0'), + new UFixedNxM<256, 16>('2.0'), + new UFixedNxM<256, 16>('3.0'), + new UFixedNxM<256, 16>('255.0'), + new UFixedNxM<256, 16>('65536.0'), + new UFixedNxM<256, 16>('4294967295.0'), + new UFixedNxM<256, 16>('1844.6744073709551616'), + new UFixedNxM<256, 16>('340282366920938463463374.607431768211456'), + new UFixedNxM<256, 16>('11579208923731619542357098500868790785326998466564056403945758.4007913129639935'), + ] + }, + array() { + return new StaticArray, 10>(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, 10>>(asBytes(value)) + }, +} +const stringStaticArray = { + abiType: ABIType.from('string[10]'), + nativeValues() { + return [ + '', + '1', + 'hello', + 'World', + (2 ** 8).toString(), + (2 ** 16).toString(), + (2 ** 32).toString(), + (2 ** 64).toString(), + (2 ** 128).toString(), + (2 ** 256).toString(), + ] + }, + abiValues() { + return this.nativeValues().map((v) => new Str(v)) + }, + array() { + return new StaticArray(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>(asBytes(value)) + }, +} +const addressStaticArrayOfArray = { + abiType: ABIType.from('address[10][2]'), + nativeValues() { + return [addressStaticArray.nativeValues(), addressStaticArray.nativeValues().reverse()] + }, + abiValues() { + return this.nativeValues().map((a) => new StaticArray(...a.map((v) => new Address(Bytes(v))))) + }, + array() { + return new StaticArray, 2>(...this.abiValues().map((a) => new StaticArray(...a))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, 2>>(asBytes(value)) + }, +} +const boolStaticArrayOfArray = { + abiType: ABIType.from('bool[10][2]'), + nativeValues() { + return [boolStaticArray.nativeValues(), boolStaticArray.nativeValues().reverse()] + }, + abiValues() { + return this.nativeValues().map((a) => new StaticArray(...a.map((v) => new Bool(v)))) + }, + array() { + return new StaticArray, 2>(...this.abiValues().map((a) => new StaticArray(...a))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, 2>>(asBytes(value)) + }, +} +const uint256StaticArrayOfArray = { + abiType: ABIType.from('uint256[10][2]'), + nativeValues() { + return [uint256StaticArray.nativeValues(), uint256StaticArray.nativeValues().reverse()] + }, + abiValues() { + return this.nativeValues().map((a) => new StaticArray, 10>(...a.map((v) => new UintN<256>(v)))) + }, + array() { + return new StaticArray, 10>, 2>(...this.abiValues().map((a) => new StaticArray, 10>(...a))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, 10>, 2>>(asBytes(value)) + }, +} +const uint256StaticArrayOfDynamicArray = { + abiType: ABIType.from('uint256[][2]'), + nativeValues() { + return [uint256StaticArray.nativeValues(), uint256StaticArray.nativeValues().reverse()] + }, + abiValues() { + 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))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>, 2>>(asBytes(value)) + }, +} +const stringStaticArrayOfArray = { + abiType: ABIType.from('string[10][2]'), + nativeValues() { + return [stringStaticArray.nativeValues(), stringStaticArray.nativeValues().reverse()] + }, + abiValues() { + return this.nativeValues().map((a) => new StaticArray(...a.map((v) => new Str(v)))) + }, + array() { + return new StaticArray, 2>(...this.abiValues().map((a) => new StaticArray(...a))) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, 2>>(asBytes(value)) + }, +} +const stringStaticArrayOfArrayOfArray = { + abiType: ABIType.from('string[10][3][2]'), + nativeValues() { + return [ + [stringStaticArray.nativeValues(), stringStaticArray.nativeValues().reverse(), stringStaticArray.nativeValues()], + [stringStaticArray.nativeValues().reverse(), stringStaticArray.nativeValues(), stringStaticArray.nativeValues().reverse()], + ] + }, + abiValues() { + return this.nativeValues().map( + (x) => new StaticArray, 3>(...x.map((y) => new StaticArray(...y.map((v) => new Str(v))))), + ) + }, + array() { + return new StaticArray, 3>, 2>( + ...this.abiValues().map((x) => new StaticArray, 3>(...x)), + ) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, 3>, 2>>(asBytes(value)) + }, +} +const tupleStaticArray = { + abiType: ABIType.from('(string[],(string[],string,uint256,address),bool,uint256[3])[2]'), + nativeValues() { + return Array(2).fill([ + stringStaticArray.nativeValues().slice(0, 2), + [ + stringStaticArray.nativeValues().slice(6, 8), + stringStaticArray.nativeValues()[9], + uint256StaticArray.nativeValues()[4], + addressStaticArray.nativeValues()[5], + ], + boolStaticArray.nativeValues()[3], + uint256StaticArray.nativeValues().slice(4, 7), + ]) + }, + abiValues() { + return Array(2).fill( + new Tuple( + ...[ + new DynamicArray(...stringStaticArray.abiValues().slice(0, 2)), + new Tuple<[DynamicArray, Str, UintN<256>, Address]>( + new DynamicArray(...stringStaticArray.abiValues().slice(6, 8)), + stringStaticArray.abiValues()[9], + uint256StaticArray.abiValues()[4], + addressStaticArray.abiValues()[5], + ), + boolStaticArray.abiValues()[3], + new StaticArray, 3>(...uint256StaticArray.abiValues().slice(4, 7)), + ], + ), + ) + }, + array() { + return new StaticArray< + Tuple<[DynamicArray, Tuple<[DynamicArray, Str, UintN<256>, Address]>, Bool, StaticArray, 3>]>, + 2 + >(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4< + StaticArray, Tuple<[DynamicArray, Str, UintN<256>, Address]>, Bool, StaticArray, 3>]>, 2> + >(asBytes(value)) + }, +} +class Swapped extends Struct<{ + b: UintN<256> + c: Bool + d: Str + a: Tuple<[DynamicArray, DynamicArray, Str, UintN<256>, Bool, StaticArray, 3>]> +}> {} +const structStaticArray = { + abiType: ABIType.from('(uint256,bool,string,(string[],string[],string,uint256,bool,uint256[3]))[2]'), + nativeValues() { + return Array(2).fill([ + uint256StaticArray.nativeValues()[0], + boolStaticArray.nativeValues()[1], + stringStaticArray.nativeValues()[2], + [ + [stringStaticArray.nativeValues()[3], stringStaticArray.nativeValues()[4]], + [stringStaticArray.nativeValues()[5], stringStaticArray.nativeValues()[6]], + stringStaticArray.nativeValues()[7], + uint256StaticArray.nativeValues()[1], + boolStaticArray.nativeValues()[2], + [uint256StaticArray.nativeValues()[2], uint256StaticArray.nativeValues()[3], uint256StaticArray.nativeValues()[4]], + ], + ]) + }, + abiValues() { + return Array(2).fill( + new Swapped({ + b: uint256StaticArray.abiValues()[0], + c: boolStaticArray.abiValues()[1], + d: stringStaticArray.abiValues()[2], + a: new Tuple( + new DynamicArray(stringStaticArray.abiValues()[3], stringStaticArray.abiValues()[4]), + new DynamicArray(stringStaticArray.abiValues()[5], stringStaticArray.abiValues()[6]), + stringStaticArray.abiValues()[7], + uint256StaticArray.abiValues()[1], + boolStaticArray.abiValues()[2], + new StaticArray, 3>( + uint256StaticArray.abiValues()[2], + uint256StaticArray.abiValues()[3], + uint256StaticArray.abiValues()[4], + ), + ), + }), + ) + }, + array() { + return new StaticArray(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4>(asBytes(value)) + }, +} + +describe('arc4.StaticArray', async () => { + const ctx = new TestExecutionContext() + afterEach(async () => { + ctx.reset() + }) + + test.each([ + addressStaticArray, + boolStaticArray, + uint256StaticArray, + ufixednxmStaticArray, + stringStaticArray, + addressStaticArrayOfArray, + boolStaticArrayOfArray, + uint256StaticArrayOfArray, + uint256StaticArrayOfDynamicArray, + stringStaticArrayOfArray, + stringStaticArrayOfArrayOfArray, + tupleStaticArray, + structStaticArray, + ])('should be able to get bytes representation', async (data) => { + const sdkResult = data.abiType.encode(data.nativeValues()) + const result = data.array().bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + + test.each([ + addressStaticArray, + boolStaticArray, + uint256StaticArray, + ufixednxmStaticArray, + stringStaticArray, + addressStaticArrayOfArray, + boolStaticArrayOfArray, + uint256StaticArrayOfArray, + uint256StaticArrayOfDynamicArray, + stringStaticArrayOfArray, + stringStaticArrayOfArrayOfArray, + tupleStaticArray, + structStaticArray, + ])('copy static array', async (data) => { + const sdkResult = data.abiType.encode(data.nativeValues()) + const original = data.array() + const copy = original.copy() + const result = copy.bytes + expect(copy.length).toEqual(original.length) + expect(result).toEqual(sdkResult) + }) + + test.each([ + addressStaticArray, + boolStaticArray, + uint256StaticArray, + ufixednxmStaticArray, + stringStaticArray, + addressStaticArrayOfArray, + boolStaticArrayOfArray, + uint256StaticArrayOfArray, + uint256StaticArrayOfDynamicArray, + stringStaticArrayOfArray, + stringStaticArrayOfArrayOfArray, + tupleStaticArray, + structStaticArray, + ])('get item from static array', async (data) => { + const staticArray = data.array() + const nativeValues = data.nativeValues() + for (let i = 0; i < staticArray.length; i++) { + compareARC4AndABIValue(staticArray[i], nativeValues[i]) + } + expect(staticArray.length).toEqual(nativeValues.length) + }) + + test.each([ + addressStaticArray, + boolStaticArray, + uint256StaticArray, + ufixednxmStaticArray, + stringStaticArray, + addressStaticArrayOfArray, + boolStaticArrayOfArray, + uint256StaticArrayOfArray, + uint256StaticArrayOfDynamicArray, + stringStaticArrayOfArray, + stringStaticArrayOfArrayOfArray, + tupleStaticArray, + structStaticArray, + ])('set item in static array', async (data) => { + const nativeValues = data.nativeValues() + const nativeValuesCopy = [...nativeValues] + const nativeTemp = nativeValuesCopy.at(-1)! + nativeValuesCopy[nativeValuesCopy.length - 1] = nativeValuesCopy[0] + nativeValuesCopy[0] = nativeTemp + + const staticArray = data.array() + const staticArrayCopy = staticArray.copy() + const arrayTemp = staticArrayCopy.at(-1) + staticArrayCopy[staticArrayCopy.length - 1] = staticArrayCopy[0] + staticArrayCopy[0] = arrayTemp + + const sdkResult = data.abiType.encode(nativeValuesCopy) + const result = staticArrayCopy.bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + + test.each([ + addressStaticArray, + boolStaticArray, + uint256StaticArray, + ufixednxmStaticArray, + stringStaticArray, + addressStaticArrayOfArray, + boolStaticArrayOfArray, + uint256StaticArrayOfArray, + uint256StaticArrayOfDynamicArray, + stringStaticArrayOfArray, + stringStaticArrayOfArrayOfArray, + tupleStaticArray, + structStaticArray, + ])('create static array from bytes', async (data) => { + const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const result = data.create(Bytes(sdkEncodedBytes)) + const nativeValues = data.nativeValues() + for (let i = 0; i < result.length; i++) { + compareARC4AndABIValue(result[i], nativeValues[i]) + } + }) + + test.each([ + addressStaticArray, + boolStaticArray, + uint256StaticArray, + ufixednxmStaticArray, + stringStaticArray, + addressStaticArrayOfArray, + boolStaticArrayOfArray, + uint256StaticArrayOfArray, + uint256StaticArrayOfDynamicArray, + stringStaticArrayOfArray, + stringStaticArrayOfArrayOfArray, + tupleStaticArray, + structStaticArray, + ])('get item from static array created from bytes', async (data) => { + const nativeValues = data.nativeValues() + const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const staticArray = data.create(Bytes(sdkEncodedBytes)) + for (let i = 0; i < staticArray.length; i++) { + compareARC4AndABIValue(staticArray[i], nativeValues[i]) + } + expect(staticArray.length).toEqual(nativeValues.length) + }) + + test.each([ + addressStaticArray, + boolStaticArray, + uint256StaticArray, + ufixednxmStaticArray, + stringStaticArray, + addressStaticArrayOfArray, + boolStaticArrayOfArray, + uint256StaticArrayOfArray, + uint256StaticArrayOfDynamicArray, + stringStaticArrayOfArray, + stringStaticArrayOfArrayOfArray, + tupleStaticArray, + structStaticArray, + ])('set item in static array created from bytes', async (data) => { + const nativeValues = data.nativeValues() + const nativeValuesCopy = [...nativeValues] + const nativeTemp = nativeValuesCopy.at(-1)! + nativeValuesCopy[nativeValuesCopy.length - 1] = nativeValuesCopy[0] + nativeValuesCopy[0] = nativeTemp + + const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const staticArray = data.create(Bytes(sdkEncodedBytes)) + const staticArrayCopy = staticArray.copy() + const arrayTemp = staticArrayCopy.at(-1) + staticArrayCopy[staticArrayCopy.length - 1] = staticArrayCopy[0] + staticArrayCopy[0] = arrayTemp + + const sdkResult = data.abiType.encode(nativeValuesCopy) + const result = staticArrayCopy.bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + + it('set item in nested static array', async () => { + const data = stringStaticArrayOfArrayOfArray + const nativeValues = data.nativeValues() + nativeValues[0][0][0] = 'new value' + + const staticArray = data.array() + staticArray[0][0][0] = new Str('new value') + + const sdkResult = data.abiType.encode(nativeValues) + const result = staticArray.bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + + it('set item in nested static array create from bytes', async () => { + const data = stringStaticArrayOfArrayOfArray + const nativeValues = data.nativeValues() + nativeValues[0][0][0] = 'new value' + + const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const staticArray = data.create(Bytes(sdkEncodedBytes)) + staticArray[0][0][0] = new Str('new value') + + const sdkResult = data.abiType.encode(nativeValues) + const result = staticArray.bytes + expect(result).toEqual(Bytes(sdkResult)) + }) +}) + +const compareARC4AndABIValue = (arc4Value: DeliberateAny, nativeValue: DeliberateAny) => { + if (arc4Value instanceof StaticArray || arc4Value instanceof DynamicArray) { + for (let i = 0; i < arc4Value.length; i++) { + compareARC4AndABIValue(arc4Value[i], nativeValue[i]) + } + } else if (arc4Value instanceof Tuple) { + const tupleValues = arc4Value.native + for (let i = 0; i < arc4Value.length; i++) { + compareARC4AndABIValue(tupleValues[i], nativeValue[i]) + } + } else if (arc4Value instanceof Struct) { + const structValues = Object.values(arc4Value.items) + for (let i = 0; i < structValues.length; i++) { + compareARC4AndABIValue(structValues[i], nativeValue[i]) + } + } else if (arc4Value.native !== undefined) { + if (arc4Value.native instanceof AccountCls) { + expect(arc4Value.native.bytes).toEqual(nativeValue) + } else { + expect(arc4Value.native).toEqual(nativeValue) + } + } else { + expect(arc4Value.bytes).toEqual(encodingUtil.bigIntToUint8Array(arc4Value, arc4Value.bytes.length)) + } +} diff --git a/tests/arc4/static-bytes.spec.ts b/tests/arc4/static-bytes.spec.ts new file mode 100644 index 0000000..ed71e3d --- /dev/null +++ b/tests/arc4/static-bytes.spec.ts @@ -0,0 +1,56 @@ +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { interpretAsArc4, StaticBytes } from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' +import { ABIType } from 'algosdk' +import { describe, expect, test } from 'vitest' + +const testData = [ + { + abiType() { + return ABIType.from(`byte[${this.nativeValue().length}]`) + }, + nativeValue() { + return [0, 1, 8, 16, 32, 64, 128, 255, 20, 30, 40, 50, 111] + }, + staticBytes() { + return new StaticBytes<13>(Bytes(this.nativeValue())) + }, + }, + { + abiType() { + return ABIType.from(`byte[${this.nativeValue().length}]`) + }, + nativeValue() { + return encodingUtil.utf8ToUint8Array('01ff99aa'.repeat(8)) + }, + staticBytes() { + return new StaticBytes<64>('01ff99aa'.repeat(8)) + }, + }, +] + +describe('arc4.StaticBytes', async () => { + test.each(testData)('should be able to get bytes representation', async (data) => { + const sdkResult = data.abiType().encode(data.nativeValue()) + const result = 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() + for (let i = 0; i < staticArray.length; i++) { + expect(staticArray[i].native).toEqual(nativeValue[i]) + } + expect(staticArray.length).toEqual(nativeValue.length) + }) + + test.each(testData)('create static bytes from bytes', async (data) => { + const nativeValue = data.nativeValue() + const sdkEncodedBytes = data.abiType().encode(nativeValue) + const result = interpretAsArc4(Bytes(sdkEncodedBytes)) + for (let i = 0; i < result.length; i++) { + expect(result[i].native).toEqual(nativeValue[i]) + } + }) +}) diff --git a/tests/arc4/struct.spec.ts b/tests/arc4/struct.spec.ts new file mode 100644 index 0000000..a9f8137 --- /dev/null +++ b/tests/arc4/struct.spec.ts @@ -0,0 +1,319 @@ +import { Bytes, internal } from '@algorandfoundation/algorand-typescript' +import { Bool, DynamicArray, interpretAsArc4, StaticArray, Str, Struct, Tuple, UintN } from '@algorandfoundation/algorand-typescript/arc4' +import { ABIType } from 'algosdk' + +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 { asBytes } from '../../src/util' + +const nativeString = 'hello' +const nativeNumber = 42 +const nativeBool = true + +const abiString = new Str('hello') +const abiUint64 = new UintN<64>(42) +const abiBool = new Bool(true) + +class Swapped1 extends Struct<{ + b: UintN<64> + c: Bool + d: Str + a: Tuple<[UintN<64>, Bool, Bool]> +}> {} + +class Swapped2 extends Struct<{ + b: UintN<64> + c: Bool + d: Str + a: Tuple<[Tuple<[UintN<64>, Bool, Bool]>, Tuple<[UintN<64>, Bool, Bool]>]> +}> {} + +class Swapped3 extends Struct<{ + b: UintN<64> + c: Bool + d: Str + a: Tuple<[DynamicArray, DynamicArray, Str, UintN<64>, Bool, StaticArray, 3>]> +}> {} + +class Swapped4 extends Struct<{ + b: UintN<64> + c: Bool + d: Str + a: Tuple<[Tuple<[Bool, DynamicArray, Str]>, UintN<64>, StaticArray, 3>]> +}> {} + +class Swapped5 extends Struct<{ + b: UintN<64> + c: Bool + d: Str + a: Tuple<[Tuple<[Bool, DynamicArray, Str]>, Tuple<[UintN<64>, StaticArray, 3>]>]> +}> {} + +class Swapped6 extends Struct<{ + b: UintN<64> + c: Bool + d: Str + a: Tuple<[Tuple<[Bool, Tuple<[DynamicArray, Str]>]>, Tuple<[UintN<64>, StaticArray, 3>]>]> +}> {} + +const testData = [ + { + abiType: ABIType.from('(uint64,bool,string,(uint64,bool,bool))'), + nativeValues() { + return [nativeNumber, nativeBool, nativeString, [nativeNumber, nativeBool, nativeBool]] + }, + abiValues() { + return { b: abiUint64, c: abiBool, d: abiString, a: new Tuple(abiUint64, abiBool, abiBool) } as Swapped1 + }, + struct() { + return new Swapped1(this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4(asBytes(value)) + }, + }, + { + abiType: ABIType.from('(uint64,bool,string,((uint64,bool,bool),(uint64,bool,bool)))'), + nativeValues() { + return [ + nativeNumber, + nativeBool, + nativeString, + [ + [nativeNumber, nativeBool, nativeBool], + [nativeNumber, nativeBool, nativeBool], + ], + ] + }, + abiValues() { + return { + b: abiUint64, + c: abiBool, + d: abiString, + a: new Tuple(new Tuple(abiUint64, abiBool, abiBool), new Tuple(abiUint64, abiBool, abiBool)), + } as Swapped2 + }, + struct() { + return new Swapped2(this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4(asBytes(value)) + }, + }, + { + abiType: ABIType.from('(uint64,bool,string,(string[],string[],string,uint64,bool,uint64[3]))'), + nativeValues() { + return [ + nativeNumber, + nativeBool, + nativeString, + [ + [nativeString, nativeString], + [nativeString, nativeString], + nativeString, + nativeNumber, + nativeBool, + [nativeNumber, nativeNumber, nativeNumber], + ], + ] + }, + abiValues() { + return { + b: abiUint64, + c: abiBool, + d: abiString, + a: new Tuple( + new DynamicArray(abiString, abiString), + new DynamicArray(abiString, abiString), + abiString, + abiUint64, + abiBool, + new StaticArray, 3>(abiUint64, abiUint64, abiUint64), + ), + } as Swapped3 + }, + struct() { + return new Swapped3(this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4(asBytes(value)) + }, + }, + { + abiType: ABIType.from('(uint64,bool,string,((bool,string[],string),uint64,uint64[3]))'), + nativeValues() { + return [ + nativeNumber, + nativeBool, + nativeString, + [[nativeBool, [nativeString, nativeString], nativeString], nativeNumber, [nativeNumber, nativeNumber, nativeNumber]], + ] + }, + abiValues() { + return { + b: abiUint64, + c: abiBool, + d: abiString, + a: new Tuple( + new Tuple(abiBool, new DynamicArray(abiString, abiString), abiString), + abiUint64, + new StaticArray, 3>(abiUint64, abiUint64, abiUint64), + ), + } as Swapped4 + }, + struct() { + return new Swapped4(this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4(asBytes(value)) + }, + }, + { + abiType: ABIType.from('(uint64,bool,string,((bool,string[],string),(uint64,uint64[3])))'), + nativeValues() { + return [ + nativeNumber, + nativeBool, + nativeString, + [ + [nativeBool, [nativeString, nativeString], nativeString], + [nativeNumber, [nativeNumber, nativeNumber, nativeNumber]], + ], + ] + }, + abiValues() { + return { + b: abiUint64, + c: abiBool, + d: abiString, + a: new Tuple( + new Tuple(abiBool, new DynamicArray(abiString, abiString), abiString), + new Tuple(abiUint64, new StaticArray, 3>(abiUint64, abiUint64, abiUint64)), + ), + } as Swapped5 + }, + struct() { + return new Swapped5(this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4(asBytes(value)) + }, + }, + { + abiType: ABIType.from('(uint64,bool,string,((bool,(string[],string)),(uint64,uint64[3])))'), + nativeValues() { + return [ + nativeNumber, + nativeBool, + nativeString, + [ + [nativeBool, [[nativeString, nativeString], nativeString]], + [nativeNumber, [nativeNumber, nativeNumber, nativeNumber]], + ], + ] + }, + abiValues() { + return { + b: abiUint64, + c: abiBool, + d: abiString, + a: new Tuple( + new Tuple(abiBool, new Tuple(new DynamicArray(abiString, abiString), abiString)), + new Tuple(abiUint64, new StaticArray, 3>(abiUint64, abiUint64, abiUint64)), + ), + } as Swapped6 + }, + struct() { + return new Swapped6(this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4(asBytes(value)) + }, + }, +] + +describe('arc4.Struct', async () => { + test.each(testData)('should be able to get bytes representation', async (data) => { + const sdkResult = data.abiType.encode(data.nativeValues()) + const result = data.struct() + expect(result.bytes).toEqual(sdkResult) + }) + + test.each(testData)('create struct from bytes', async (data) => { + const nativeValues = data.nativeValues() + const sdkResult = data.abiType.encode(nativeValues) + const result = data.create(Bytes(sdkResult)) + + let i = 0 + compareARC4AndABIValue(result.b, nativeValues[i++]) + compareARC4AndABIValue(result.c, nativeValues[i++]) + compareARC4AndABIValue(result.d, nativeValues[i++]) + compareARC4AndABIValue(result.a, nativeValues[i++]) + }) + + 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 = data.abiType.encode(nativeValues) + + const abiValues = data.struct() as Swapped6 + abiValues.b = new UintN<64>(43) + abiValues.d = new Str('world') + abiValues.a.at(0).at(1).at(0)[1] = new Str('hello, world') + abiValues.a.at(0).at(1).at(0).push(new Str('test')) + abiValues.a.at(1).at(1)[0] = new UintN<64>(24) + const result = abiValues.bytes + + expect(result).toEqual(Bytes(sdkResult)) + }) + + it('set item in struct created from bytes', 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 = data.abiType.encode(nativeValues) + + const bytes = Bytes(data.abiType.encode(data.nativeValues())) + const abiValues = data.create(bytes) as Swapped6 + abiValues.b = new UintN<64>(43) + abiValues.d = new Str('world') + abiValues.a.at(0).at(1).at(0)[1] = new Str('hello, world') + abiValues.a.at(0).at(1).at(0).push(new Str('test')) + abiValues.a.at(1).at(1)[0] = new UintN<64>(24) + const result = abiValues.bytes + + expect(result).toEqual(Bytes(sdkResult)) + }) +}) + +const compareARC4AndABIValue = (arc4Value: DeliberateAny, nativeValue: DeliberateAny) => { + if (arc4Value instanceof StaticArray || arc4Value instanceof DynamicArray) { + for (let i = 0; i < arc4Value.length; i++) { + compareARC4AndABIValue(arc4Value[i], nativeValue[i]) + } + } else if (arc4Value instanceof Tuple) { + const tupleValues = arc4Value.native + for (let i = 0; i < arc4Value.length; i++) { + compareARC4AndABIValue(tupleValues[i], nativeValue[i]) + } + } else if (arc4Value.native !== undefined) { + if (arc4Value.native instanceof AccountCls) { + expect(arc4Value.native.bytes).toEqual(nativeValue) + } else { + expect(arc4Value.native).toEqual(nativeValue) + } + } else { + expect(arc4Value.bytes).toEqual(encodingUtil.bigIntToUint8Array(arc4Value, arc4Value.bytes.length)) + } +} diff --git a/tests/arc4/tuple.spec.ts b/tests/arc4/tuple.spec.ts new file mode 100644 index 0000000..78e8627 --- /dev/null +++ b/tests/arc4/tuple.spec.ts @@ -0,0 +1,360 @@ +import { Bytes, internal } 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 { ABIType } from 'algosdk' +import { afterEach, describe, expect, test } from 'vitest' +import { AccountCls } from '../../src/impl/account' +import { DeliberateAny } from '../../src/typescript-helpers' +import { asBytes, asUint8Array } from '../../src/util' + +const nativeString = 'hello' +const nativeNumber = 42 +const nativeBool = true +const nativeAddress = asUint8Array(Bytes.fromHex(`${'00'.repeat(31)}ff`)) + +const otherNativeString = 'hello' +const otherNativeNumber = 42 + +const abiString = new Str('hello') +const abiUint8 = new UintN<8>(42) +const abiBool = new Bool(true) +const abiAddress = new Address(Bytes.fromHex(`${'00'.repeat(31)}ff`)) + +const otherAbiString = new Str('hello') +const otherAbiUint8 = new UintN<8>(42) + +const testData = [ + { + abiType: ABIType.from('(uint8,bool,bool,address)'), + nativeValues() { + return [nativeNumber, nativeBool, nativeBool, nativeAddress] + }, + abiValues() { + return [abiUint8, abiBool, abiBool, abiAddress] as readonly [UintN<8>, Bool, Bool, Address] + }, + tuple() { + return new Tuple<[UintN<8>, Bool, Bool, Address]>(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, Bool, Bool, Address]>>(asBytes(value)) + }, + }, + { + abiType: ABIType.from('(string,uint8,bool)'), + nativeValues() { + return [nativeString, nativeNumber, nativeBool] + }, + abiValues() { + return [abiString, abiUint8, abiBool] as readonly [Str, UintN<8>, Bool] + }, + tuple() { + return new Tuple<[Str, UintN<8>, Bool]>(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, Bool]>>(asBytes(value)) + }, + }, + { + abiType: ABIType.from('((uint8,bool,bool),(uint8,bool,bool))'), + nativeValues() { + return [ + [nativeNumber, nativeBool, nativeBool], + [nativeNumber, nativeBool, nativeBool], + ] + }, + abiValues() { + return [ + new Tuple<[UintN<8>, Bool, Bool]>(abiUint8, abiBool, abiBool), + new Tuple<[UintN<8>, Bool, Bool]>(abiUint8, abiBool, abiBool), + ] as readonly [Tuple<[UintN<8>, Bool, Bool]>, Tuple<[UintN<8>, Bool, Bool]>] + }, + tuple() { + return new Tuple<[Tuple<[UintN<8>, Bool, Bool]>, Tuple<[UintN<8>, Bool, Bool]>]>(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, Bool, Bool]>, Tuple<[UintN<8>, Bool, Bool]>]>>(asBytes(value)) + }, + }, + { + abiType: ABIType.from('(string[],string[],string,uint8,bool,uint8[3])'), + nativeValues() { + return [ + [nativeString, nativeString], + [nativeString, nativeString], + nativeString, + nativeNumber, + nativeBool, + [nativeNumber, nativeNumber, nativeNumber], + ] + }, + abiValues() { + return [ + new DynamicArray(abiString, abiString), + new DynamicArray(abiString, abiString), + abiString, + abiUint8, + abiBool, + new StaticArray(abiUint8, abiUint8, abiUint8), + ] as readonly [DynamicArray, DynamicArray, Str, UintN<8>, Bool, StaticArray, 3>] + }, + tuple() { + return new Tuple<[DynamicArray, DynamicArray, Str, UintN<8>, Bool, StaticArray, 3>]>(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, DynamicArray, Str, UintN<8>, Bool, StaticArray, 3>]>>(asBytes(value)) + }, + }, + { + abiType: ABIType.from('((bool,string[],string),uint8,uint8[3])'), + nativeValues() { + return [[nativeBool, [nativeString, nativeString], nativeString], nativeNumber, [nativeNumber, nativeNumber, nativeNumber]] + }, + abiValues() { + return [ + new Tuple<[Bool, DynamicArray, Str]>(abiBool, new DynamicArray(abiString, abiString), abiString), + abiUint8, + new StaticArray(abiUint8, abiUint8, abiUint8), + ] as readonly [Tuple<[Bool, DynamicArray, Str]>, UintN<8>, StaticArray, 3>] + }, + tuple() { + return new Tuple<[Tuple<[Bool, DynamicArray, Str]>, UintN<8>, StaticArray, 3>]>(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, Str]>, UintN<8>, StaticArray, 3>]>>(asBytes(value)) + }, + }, + { + abiType: ABIType.from('((bool,string[],string),(uint8,uint8[3]))'), + nativeValues() { + return [ + [nativeBool, [nativeString, nativeString], nativeString], + [nativeNumber, [nativeNumber, nativeNumber, nativeNumber]], + ] + }, + abiValues() { + return [ + new Tuple<[Bool, DynamicArray, Str]>(abiBool, new DynamicArray(abiString, abiString), abiString), + new Tuple<[UintN<8>, StaticArray, 3>]>(abiUint8, new StaticArray(abiUint8, abiUint8, abiUint8)), + ] as readonly [Tuple<[Bool, DynamicArray, Str]>, Tuple<[UintN<8>, StaticArray, 3>]>] + }, + tuple() { + return new Tuple<[Tuple<[Bool, DynamicArray, Str]>, Tuple<[UintN<8>, StaticArray, 3>]>]>(...this.abiValues()) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, Str]>, Tuple<[UintN<8>, StaticArray, 3>]>]>>(asBytes(value)) + }, + }, + { + abiType: ABIType.from('((bool,(string[],string,address)),(uint8,uint8[3]))'), + nativeValues() { + return [ + [nativeBool, [[nativeString, nativeString], nativeString, nativeAddress]], + [nativeNumber, [nativeNumber, nativeNumber, nativeNumber]], + ] + }, + abiValues() { + return [ + new Tuple<[Bool, Tuple<[DynamicArray, Str, Address]>]>( + abiBool, + new Tuple<[DynamicArray, Str, Address]>(new DynamicArray(abiString, abiString), abiString, abiAddress), + ), + new Tuple<[UintN<8>, StaticArray, 3>]>(abiUint8, new StaticArray(abiUint8, abiUint8, abiUint8)), + ] as readonly [Tuple<[Bool, Tuple<[DynamicArray, Str, Address]>]>, Tuple<[UintN<8>, StaticArray, 3>]>] + }, + tuple() { + return new Tuple<[Tuple<[Bool, Tuple<[DynamicArray, Str, Address]>]>, Tuple<[UintN<8>, StaticArray, 3>]>]>( + ...this.abiValues(), + ) + }, + create(value: internal.primitives.StubBytesCompat) { + return interpretAsArc4, Str, Address]>]>, Tuple<[UintN<8>, StaticArray, 3>]>]>>( + asBytes(value), + ) + }, + }, +] + +const testDataWithArray = [ + { + abiType: ABIType.from('(string[],string[],string,uint8,bool,uint8[3])'), + updatedNativeValues() { + return [ + [otherNativeString, nativeString, otherNativeString], + [otherNativeString, nativeString, otherNativeString], + nativeString, + nativeNumber, + nativeBool, + [otherNativeNumber, nativeNumber, otherNativeNumber], + ] + }, + abiValues() { + return [ + new DynamicArray(abiString, abiString), + new DynamicArray(abiString, abiString), + abiString, + abiUint8, + abiBool, + new StaticArray(abiUint8, abiUint8, abiUint8), + ] as readonly [DynamicArray, DynamicArray, Str, UintN<8>, Bool, StaticArray, 3>] + }, + tuple() { + return new Tuple<[DynamicArray, DynamicArray, Str, UintN<8>, Bool, StaticArray, 3>]>(...this.abiValues()) + }, + update(value: Tuple<[DynamicArray, DynamicArray, Str, UintN<8>, Bool, StaticArray, 3>]>) { + value.native[0][0] = otherAbiString + value.native[0].push(otherAbiString) + value.native[1][0] = otherAbiString + value.native[1].push(otherAbiString) + value.native[5][0] = otherAbiUint8 + value.native[5][2] = otherAbiUint8 + }, + }, + { + abiType: ABIType.from('((bool,string[],string),uint8,uint8[3])'), + updatedNativeValues() { + return [ + [nativeBool, [otherNativeString, nativeString, otherNativeString], nativeString], + nativeNumber, + [otherNativeNumber, nativeNumber, otherNativeNumber], + ] + }, + abiValues() { + return [ + new Tuple<[Bool, DynamicArray, Str]>(abiBool, new DynamicArray(abiString, abiString), abiString), + abiUint8, + new StaticArray(abiUint8, abiUint8, abiUint8), + ] as readonly [Tuple<[Bool, DynamicArray, Str]>, UintN<8>, StaticArray, 3>] + }, + tuple() { + return new Tuple<[Tuple<[Bool, DynamicArray, Str]>, UintN<8>, StaticArray, 3>]>(...this.abiValues()) + }, + update(value: Tuple<[Tuple<[Bool, DynamicArray, Str]>, UintN<8>, StaticArray, 3>]>) { + value.native[0].native[1][0] = otherAbiString + value.native[0].native[1].push(otherAbiString) + value.native[2][0] = otherAbiUint8 + value.native[2][2] = otherAbiUint8 + }, + }, + { + abiType: ABIType.from('((bool,string[],string),(uint8,uint8[3]))'), + updatedNativeValues() { + return [ + [nativeBool, [otherNativeString, nativeString, otherNativeString], nativeString], + [nativeNumber, [otherNativeNumber, nativeNumber, otherNativeNumber]], + ] + }, + abiValues() { + return [ + new Tuple<[Bool, DynamicArray, Str]>(abiBool, new DynamicArray(abiString, abiString), abiString), + new Tuple<[UintN<8>, StaticArray, 3>]>(abiUint8, new StaticArray(abiUint8, abiUint8, abiUint8)), + ] as readonly [Tuple<[Bool, DynamicArray, Str]>, Tuple<[UintN<8>, StaticArray, 3>]>] + }, + tuple() { + return new Tuple<[Tuple<[Bool, DynamicArray, Str]>, Tuple<[UintN<8>, StaticArray, 3>]>]>(...this.abiValues()) + }, + update(value: Tuple<[Tuple<[Bool, DynamicArray, Str]>, Tuple<[UintN<8>, StaticArray, 3>]>]>) { + value.native[0].native[1][0] = otherAbiString + value.native[0].native[1].push(otherAbiString) + value.native[1].native[1][0] = otherAbiUint8 + value.native[1].native[1][2] = otherAbiUint8 + }, + }, + { + abiType: ABIType.from('((bool,(string[],string,address)),(uint8,uint8[3]))'), + updatedNativeValues() { + return [ + [nativeBool, [[otherNativeString, nativeString, otherNativeString], nativeString, nativeAddress]], + [nativeNumber, [otherNativeNumber, nativeNumber, otherNativeNumber]], + ] + }, + abiValues() { + return [ + new Tuple<[Bool, Tuple<[DynamicArray, Str, Address]>]>( + abiBool, + new Tuple<[DynamicArray, Str, Address]>(new DynamicArray(abiString, abiString), abiString, abiAddress), + ), + new Tuple<[UintN<8>, StaticArray, 3>]>(abiUint8, new StaticArray(abiUint8, abiUint8, abiUint8)), + ] as readonly [Tuple<[Bool, Tuple<[DynamicArray, Str, Address]>]>, Tuple<[UintN<8>, StaticArray, 3>]>] + }, + tuple() { + return new Tuple<[Tuple<[Bool, Tuple<[DynamicArray, Str, Address]>]>, Tuple<[UintN<8>, StaticArray, 3>]>]>( + ...this.abiValues(), + ) + }, + update(value: Tuple<[Tuple<[Bool, Tuple<[DynamicArray, Str, Address]>]>, Tuple<[UintN<8>, StaticArray, 3>]>]>) { + value.native[0].native[1].native[0][0] = otherAbiString + value.native[0].native[1].native[0].push(otherAbiString) + value.native[1].native[1][0] = otherAbiUint8 + value.native[1].native[1][2] = otherAbiUint8 + }, + }, +] + +describe('arc4.Tuple', async () => { + const ctx = new TestExecutionContext() + afterEach(async () => { + ctx.reset() + }) + + test.each(testData)('should be able to get bytes representation', async (data) => { + const sdkResult = data.abiType.encode(data.nativeValues()) + const result = data.tuple().bytes + expect(result).toEqual(Bytes(sdkResult)) + }) + + test.each(testData)('should be able to get native representation', async (data) => { + const nativeValues = data.nativeValues() + const result = data.tuple().native + for (let i = 0; i < nativeValues.length; i++) { + compareARC4AndABIValue(result[i], nativeValues[i]) + } + expect(result.length).toEqual(nativeValues.length) + }) + + test.each(testData)('create tuple from bytes', async (data) => { + const nativeValues = data.nativeValues() + const sdkEncodedBytes = data.abiType.encode(nativeValues) + + const result = data.create(Bytes(sdkEncodedBytes)) + const tupleValues = result.native + + for (let i = 0; i < tupleValues.length; i++) { + compareARC4AndABIValue(tupleValues[i], nativeValues[i]) + } + }) + + test.each(testDataWithArray)('update array values in tuple', async (data) => { + const sdkResult = data.abiType.encode(data.updatedNativeValues()) + const tuple = data.tuple() + data.update(tuple as DeliberateAny) + const result = tuple.bytes + expect(result).toEqual(Bytes(sdkResult)) + + const tupleValues = tuple.native + const nativeValues = data.updatedNativeValues() + for (let i = 0; i < tupleValues.length; i++) { + compareARC4AndABIValue(tupleValues[i], nativeValues[i]) + } + }) +}) + +const compareARC4AndABIValue = (arc4Value: DeliberateAny, nativeValue: DeliberateAny) => { + if (arc4Value instanceof DynamicArray || arc4Value instanceof StaticArray) { + for (let i = 0; i < arc4Value.length; i++) { + compareARC4AndABIValue(arc4Value[i], nativeValue[i]) + } + } else if (arc4Value instanceof Tuple) { + for (let i = 0; i < arc4Value.length; i++) { + compareARC4AndABIValue(arc4Value.at(i), nativeValue[i]) + } + } else if (arc4Value.native !== undefined) { + if (arc4Value.native instanceof AccountCls) { + expect(arc4Value.native.bytes).toEqual(nativeValue) + } else { + expect(arc4Value.native).toEqual(nativeValue) + } + } else { + expect(arc4Value.bytes).toEqual(encodingUtil.bigIntToUint8Array(arc4Value, arc4Value.bytes.length)) + } +} From 4de4c08d0b3a8ce555ac2f5dfd4015c2813b8027 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 12 Dec 2024 11:41:28 +0800 Subject: [PATCH 63/85] chore: update puya-ts package version --- package-lock.json | 19 +++++++++---------- package.json | 3 +-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 31e78d3..f68a6c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,9 +81,9 @@ } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0.tgz", - "integrity": "sha512-8oh95rg9sV3xy3L0tuynlW9phhT7NO1NTiD2vq+iv8n7lXmoBWwenagNEePZSmfUOOjdJfim0cKb+BOXYG9Udg==", + "version": "1.0.0-alpha.31", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.31.tgz", + "integrity": "sha512-3RsvRBS3xiEiEkkF/41p/ooYAOrhUZXp1my03X3X63SlH2b4KcYRvJo/u1pS6w/534OJNVqQ07UIC4TN9M0TcQ==", "bundleDependencies": [ "typescript" ], @@ -92,10 +92,10 @@ "chalk": "^5.3.0", "change-case": "^5.4.4", "commander": "^12.1.0", - "cross-spawn": "^7.0.3", + "cross-spawn": "7.0.6", "glob": "^11.0.0", "polytype": "^0.17.0", - "typescript": "^5.6.2", + "typescript": "5.6.2", "upath": "^2.0.1", "zod": "^3.23.8" }, @@ -105,7 +105,7 @@ } }, "node_modules/@algorandfoundation/puya-ts/node_modules/typescript": { - "version": "5.6.3", + "version": "5.6.2", "inBundle": true, "license": "Apache-2.0", "bin": { @@ -12948,7 +12948,6 @@ "version": "5.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -14040,9 +14039,9 @@ } }, "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index 6f873fb..6f0ecde 100644 --- a/package.json +++ b/package.json @@ -56,8 +56,7 @@ "semantic-release": "^24.1.2", "tsx": "4.19.1", "typescript": "^5.6.2", - "vitest": "2.1.2", - "cross-spawn": "7.0.6" + "vitest": "2.1.2" }, "peerDependencies": { "tslib": "^2.6.2" From 01d0708ee364c8e2874d21d82e51935a91f8968e Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 13 Dec 2024 09:34:05 +0800 Subject: [PATCH 64/85] chore: pin typescript verion to match puya-ts and algo-ts chore: update puya-ts and algo-ts package version --- package-lock.json | 27 ++++++++++++++------------- package.json | 6 +++--- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index f68a6c2..6e814a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,8 @@ "hasInstallScript": true, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.19", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.31", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.20", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.32", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", @@ -50,7 +50,7 @@ "rollup": "^4.24.0", "semantic-release": "^24.1.2", "tsx": "4.19.1", - "typescript": "^5.6.2", + "typescript": "5.6.2", "vitest": "2.1.2" }, "peerDependencies": { @@ -73,17 +73,17 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.19", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.19.tgz", - "integrity": "sha512-/UsnVQgsIVVCCdrWN7m/YHIYSzg5j+RLraytqte1l+smKi01Y9878/iX4cYWB68Ur1R9nt9C8HxVOtSvHfGMHQ==", + "version": "0.0.1-alpha.20", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.20.tgz", + "integrity": "sha512-XpIxvfOQdcZV1cG4TI6pXDtvYDtReWX6xW4bEuVn9FSpVrg1Vgs0lW03QoLK1sNs38Y/oW1UV9iep1P1AJX6fA==", "peerDependencies": { "tslib": "^2.6.2" } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0-alpha.31", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.31.tgz", - "integrity": "sha512-3RsvRBS3xiEiEkkF/41p/ooYAOrhUZXp1my03X3X63SlH2b4KcYRvJo/u1pS6w/534OJNVqQ07UIC4TN9M0TcQ==", + "version": "1.0.0-alpha.32", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.32.tgz", + "integrity": "sha512-9mMS8v9AksNDS9rVy+KJmbUjtYvOmXQh8ThNZ+yyvFct+vhEdiBTBnoaUsOXsTjpMtchh1GHUkjjtVKhHUuRsg==", "bundleDependencies": [ "typescript" ], @@ -97,7 +97,7 @@ "polytype": "^0.17.0", "typescript": "5.6.2", "upath": "^2.0.1", - "zod": "^3.23.8" + "zod": "^3.24.0" }, "bin": { "puya-ts": "bin/run-cli.mjs", @@ -12945,9 +12945,10 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 6f0ecde..eb6421d 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "rollup": "^4.24.0", "semantic-release": "^24.1.2", "tsx": "4.19.1", - "typescript": "^5.6.2", + "typescript": "5.6.2", "vitest": "2.1.2" }, "peerDependencies": { @@ -63,8 +63,8 @@ }, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.19", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.31", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.20", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.32", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", From ac2437be7e3d32c9632da705e257c1c48f844f7f Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Wed, 6 Nov 2024 15:30:16 +0800 Subject: [PATCH 65/85] refactor: add tests dependent upon arc4 types --- src/impl/app-global.ts | 4 +- src/impl/app-local.ts | 4 +- src/set-up.ts | 28 + src/subcontexts/contract-context.ts | 9 +- src/test-execution-context.ts | 4 +- src/util.ts | 12 +- tests/artifacts/box-contract/contract.algo.ts | 18 +- tests/artifacts/crypto-ops/contract.algo.ts | 11 +- .../artifacts/primitive-ops/contract.algo.ts | 61 +- .../data/PrimitiveOpsContract.approval.teal | 1023 ++++++----- .../data/PrimitiveOpsContract.arc32.json | 68 +- .../data/PrimitiveOpsContract.arc56.json | 1624 +++++++++++++++++ tests/artifacts/state-ops/contract.algo.ts | 332 +++- .../data/GlobalStateContract.approval.teal | 1073 +++++++++++ .../data/GlobalStateContract.arc32.json | 528 ++++++ .../data/GlobalStateContract.arc56.json | 736 ++++++++ .../data/GlobalStateContract.clear.teal | 5 + .../data/ITxnOpsContract.approval.teal | 134 ++ .../state-ops/data/ITxnOpsContract.arc32.json | 50 + .../state-ops/data/ITxnOpsContract.arc56.json | 90 + .../state-ops/data/ITxnOpsContract.clear.teal | 5 + .../data/ItxnDemoContract.approval.teal | 485 +++++ .../data/ItxnDemoContract.clear.teal | 5 + .../data/LocalStateContract.approval.teal | 802 ++++++++ .../data/LocalStateContract.arc32.json | 359 ++++ .../data/LocalStateContract.arc56.json | 507 +++++ .../data/LocalStateContract.clear.teal | 5 + .../StateAcctParamsGetContract.approval.teal | 746 ++++---- .../StateAcctParamsGetContract.arc32.json | 4 +- .../StateAcctParamsGetContract.arc56.json | 425 +++++ .../StateAcctParamsGetContract.clear.teal | 6 +- .../data/StateAppGlobalContract.approval.teal | 298 +-- .../data/StateAppGlobalContract.arc32.json | 30 +- .../data/StateAppGlobalContract.arc56.json | 260 +++ .../data/StateAppGlobalContract.clear.teal | 6 +- .../StateAppGlobalExContract.approval.teal | 118 +- .../data/StateAppGlobalExContract.arc32.json | 22 +- .../data/StateAppGlobalExContract.arc56.json | 92 + .../data/StateAppGlobalExContract.clear.teal | 6 +- .../data/StateAppLocalContract.approval.teal | 352 ++-- .../data/StateAppLocalContract.arc32.json | 8 +- .../data/StateAppLocalContract.arc56.json | 338 ++++ .../data/StateAppLocalContract.clear.teal | 6 +- .../StateAppLocalExContract.approval.teal | 116 +- .../data/StateAppLocalExContract.arc32.json | 10 +- .../data/StateAppLocalExContract.arc56.json | 106 ++ .../data/StateAppLocalExContract.clear.teal | 6 +- .../data/StateAppParamsContract.approval.teal | 541 +++--- .../data/StateAppParamsContract.arc32.json | 4 +- .../data/StateAppParamsContract.arc56.json | 307 ++++ .../data/StateAppParamsContract.clear.teal | 6 +- .../StateAssetHoldingContract.approval.teal | 114 +- .../data/StateAssetHoldingContract.arc32.json | 4 +- .../data/StateAssetHoldingContract.arc56.json | 126 ++ .../data/StateAssetHoldingContract.clear.teal | 6 +- .../StateAssetParamsContract.approval.teal | 710 ++++--- .../data/StateAssetParamsContract.arc32.json | 4 +- .../data/StateAssetParamsContract.arc56.json | 382 ++++ .../data/StateAssetParamsContract.clear.teal | 6 +- tests/avm-invoker.ts | 19 +- tests/global-state-arc4-values.spec.ts | 124 ++ tests/local-state-arc4-values.spec.ts | 111 ++ tests/log.spec.ts | 82 + tests/references/box-map.spec.ts | 182 +- tests/references/box.spec.ts | 188 +- tests/state-op-codes.spec.ts | 62 +- 66 files changed, 11592 insertions(+), 2323 deletions(-) create mode 100644 tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/GlobalStateContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/GlobalStateContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/GlobalStateContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/GlobalStateContract.clear.teal create mode 100644 tests/artifacts/state-ops/data/ITxnOpsContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/ITxnOpsContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/ITxnOpsContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/ITxnOpsContract.clear.teal create mode 100644 tests/artifacts/state-ops/data/ItxnDemoContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/ItxnDemoContract.clear.teal create mode 100644 tests/artifacts/state-ops/data/LocalStateContract.approval.teal create mode 100644 tests/artifacts/state-ops/data/LocalStateContract.arc32.json create mode 100644 tests/artifacts/state-ops/data/LocalStateContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/LocalStateContract.clear.teal create mode 100644 tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/StateAppGlobalContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/StateAppGlobalExContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/StateAppLocalContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/StateAppLocalExContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/StateAppParamsContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/StateAssetHoldingContract.arc56.json create mode 100644 tests/artifacts/state-ops/data/StateAssetParamsContract.arc56.json create mode 100644 tests/global-state-arc4-values.spec.ts create mode 100644 tests/local-state-arc4-values.spec.ts create mode 100644 tests/log.spec.ts diff --git a/src/impl/app-global.ts b/src/impl/app-global.ts index 1c31acc..eaa5470 100644 --- a/src/impl/app-global.ts +++ b/src/impl/app-global.ts @@ -1,6 +1,6 @@ import { Application, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes } from '../util' +import { asBytes, toBytes } from '../util' import { getApp } from './app-params' export const AppGlobal: internal.opTypes.AppGlobalType = { @@ -22,7 +22,7 @@ export const AppGlobal: internal.opTypes.AppGlobalType = { if (!exists) { return [Bytes(), false] } - return [state!.value as bytes, exists] + return [toBytes(state!.value), exists] }, getExUint64(a: Application | internal.primitives.StubUint64Compat, b: internal.primitives.StubBytesCompat): readonly [uint64, boolean] { const app = getApp(a) diff --git a/src/impl/app-local.ts b/src/impl/app-local.ts index f478fce..d6feb16 100644 --- a/src/impl/app-local.ts +++ b/src/impl/app-local.ts @@ -1,6 +1,6 @@ import { Account, Application, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes } from '../util' +import { asBytes, toBytes } from '../util' import { getAccount } from './acct-params' import { getApp } from './app-params' @@ -32,7 +32,7 @@ export const AppLocal: internal.opTypes.AppLocalType = { if (!exists) { return [Bytes(), false] } - return [state!.value as bytes, exists] + return [toBytes(state!.value), exists] }, getExUint64: function ( a: Account | internal.primitives.StubUint64Compat, diff --git a/src/set-up.ts b/src/set-up.ts index 718bd12..b368ebb 100644 --- a/src/set-up.ts +++ b/src/set-up.ts @@ -1,4 +1,5 @@ import { internal } from '@algorandfoundation/algorand-typescript' +import { Address } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import { AccountCls } from './impl/account' @@ -77,6 +78,33 @@ function addEqualityTesters(expectObj: ExpectObj) { // Defer to other testers return undefined }, + function AddressIsAccountStr(this: TesterContext, subject, test, customTesters): boolean | undefined { + if (subject instanceof Address) { + const testValue = typeof test === 'string' ? encodingUtil.base32ToUint8Array(test).slice(0, 32) : undefined + if (testValue !== undefined) return this.equals(subject.native.bytes, testValue, customTesters) + return undefined + } + // Defer to other testers + return undefined + }, + 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 + if (testValue !== undefined) return this.equals(subject.native.bytes, testValue, customTesters) + return undefined + } + // Defer to other testers + return undefined + }, + function AddressIsAccount(this: TesterContext, subject, test, customTesters): boolean | undefined { + if (subject instanceof Address) { + const testValue = test instanceof AccountCls ? test.bytes : undefined + if (testValue !== undefined) return this.equals(subject.native.bytes, testValue, customTesters) + return undefined + } + // Defer to other testers + return undefined + }, ]) } diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 27c71ad..f7d0a18 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -18,7 +18,7 @@ import { } from '../impl/transactions' import { getGenericTypeInfo } from '../runtime-helpers' import { DeliberateAny, IConstructor } from '../typescript-helpers' -import { asUint64Cls } from '../util' +import { toBytes } from '../util' type StateTotals = Pick @@ -76,18 +76,17 @@ const extractArraysFromArgs = (app: Application, args: DeliberateAny[]) => { const assets: Asset[] = [] const appArgs: bytes[] = [] - // TODO: replace `asUint64Cls(accounts.length).toBytes().asAlgoTs()` with `arc4.Uint8(account.length).toBytes().asAlgoTs()` for (const arg of args) { if (isTransaction(arg)) { transactions.push(arg) } else if (arg instanceof AccountCls) { - appArgs.push(asUint64Cls(accounts.length).toBytes().asAlgoTs()) + appArgs.push(toBytes(accounts.length)) accounts.push(arg as Account) } else if (arg instanceof ApplicationCls) { - appArgs.push(asUint64Cls(apps.length).toBytes().asAlgoTs()) + appArgs.push(toBytes(apps.length)) apps.push(arg as Application) } else if (arg instanceof AssetCls) { - appArgs.push(asUint64Cls(assets.length).toBytes().asAlgoTs()) + appArgs.push(toBytes(assets.length)) assets.push(arg as Asset) } } diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 99f6335..250e3ab 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -28,13 +28,13 @@ export class TestExecutionContext implements internal.ExecutionContext { #valueGenerator: ValueGenerator #defaultSender: Account - constructor() { + constructor(defaultSenderAddress?: bytes) { internal.ctxMgr.instance = this this.#contractContext = new ContractContext() this.#ledgerContext = new LedgerContext() this.#txnContext = new TransactionContext() this.#valueGenerator = new ValueGenerator() - this.#defaultSender = Account(Bytes.fromBase32(algosdk.generateAccount().addr)) + this.#defaultSender = Account(defaultSenderAddress ?? Bytes.fromBase32(algosdk.generateAccount().addr)) } account(address?: bytes): Account { diff --git a/src/util.ts b/src/util.ts index 0cd42eb..31d3211 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,4 +1,5 @@ import { Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' +import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' import { randomBytes } from 'crypto' import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT8, UINT512_SIZE } from './constants' import { BytesBackedCls, Uint64BackedCls } from './impl/base' @@ -45,7 +46,6 @@ export const asBytes = (val: internal.primitives.StubBytesCompat | Uint8Array) = export const asUint8Array = (val: internal.primitives.StubBytesCompat | Uint8Array) => asBytesCls(val).asUint8Array() -//TODO: handle arc4 types, bytes backed types export const toBytes = (val: unknown): bytes => { const uint64Val = asMaybeUint64Cls(val) if (uint64Val !== undefined) { @@ -66,17 +66,13 @@ export const toBytes = (val: unknown): bytes => { return asUint64Cls(val.uint64).toBytes().asAlgoTs() } if (Array.isArray(val)) { - // This hack handles tuples/arrays of uint64 only return val.reduce((acc: bytes, cur: unknown) => { - const uint64Val = asMaybeUint64Cls(cur) - if (!uint64Val) { - // TODO: support ABI tuple encoding - // internal.errors.internalError(`ABI tuple encoding not supported: ${nameOfType(val)}`) - return acc.concat(Bytes()) - } return acc.concat(toBytes(cur)) }, Bytes()) } + if (val instanceof ARC4Encoded) { + return val.bytes + } internal.errors.internalError(`Invalid type for bytes: ${nameOfType(val)}`) } diff --git a/tests/artifacts/box-contract/contract.algo.ts b/tests/artifacts/box-contract/contract.algo.ts index f14304d..0dbe673 100644 --- a/tests/artifacts/box-contract/contract.algo.ts +++ b/tests/artifacts/box-contract/contract.algo.ts @@ -1,18 +1,10 @@ -import { arc4, assert, Box, Bytes, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' - -// type X = [a: uint64, b: string, c: bytes] -// type Y = { a: uint64; b: string; c: bytes } -// type Z = { x: X; y: Y } +import { arc4, assert, Box, Bytes, 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') }) txn = Box({ key: Bytes('txn') }) - // a = Box({ key: Bytes('a') }) - // b = Box({ key: Bytes('b') }) - // c = Box({ key: Bytes('c') }) - // d = Box({ key: Bytes('d') }) - @arc4.abimethod() public storeEnums(): void { this.oca.value = arc4.OnCompleteAction.OptIn @@ -20,12 +12,10 @@ export class BoxContract extends arc4.Contract { } @arc4.abimethod() - public read_enums(): readonly [uint64, uint64] { + public read_enums(): Tuple<[UintN64, UintN64]> { assert(op.Box.get(Bytes('oca'))[0] === op.itob(this.oca.value)) assert(op.Box.get(Bytes('txn'))[0] === op.itob(this.txn.value)) - return [Uint64(this.oca.value), Uint64(this.txn.value)] - // TODO: use arc4 types when available - // return arc4.Tuple((arc4.UInt64(this.oca.value), arc4.UInt64(this.txn.value))) + return new Tuple(new UintN64(this.oca.value), new UintN64(this.txn.value)) } } diff --git a/tests/artifacts/crypto-ops/contract.algo.ts b/tests/artifacts/crypto-ops/contract.algo.ts index e74ae28..01455a9 100644 --- a/tests/artifacts/crypto-ops/contract.algo.ts +++ b/tests/artifacts/crypto-ops/contract.algo.ts @@ -1,4 +1,5 @@ import { arc4, bytes, Ecdsa, ensureBudget, op, OpUpFeeSource, uint64, VrfVerify } from '@algorandfoundation/algorand-typescript' +import { Bool } from '@algorandfoundation/algorand-typescript/arc4' export class CryptoOpsContract extends arc4.Contract { @arc4.abimethod() @@ -29,20 +30,18 @@ export class CryptoOpsContract extends arc4.Contract { return result } - // TODO: return arc4.Bool to match python version when arc4 types are available @arc4.abimethod() - public verify_ed25519verify(a: bytes, b: bytes, c: bytes): boolean { + public verify_ed25519verify(a: bytes, b: bytes, c: bytes): Bool { ensureBudget(1900, OpUpFeeSource.GroupCredit) const result = op.ed25519verify(a, b, c) - return result + return new Bool(result) } - // TODO: return arc4.Bool to match python version when arc4 types are available @arc4.abimethod() - public verify_ed25519verify_bare(a: bytes, b: bytes, c: bytes): boolean { + public verify_ed25519verify_bare(a: bytes, b: bytes, c: bytes): Bool { ensureBudget(1900, OpUpFeeSource.GroupCredit) const result = op.ed25519verifyBare(a, b, c) - return result + return new Bool(result) } @arc4.abimethod() diff --git a/tests/artifacts/primitive-ops/contract.algo.ts b/tests/artifacts/primitive-ops/contract.algo.ts index 0ea7097..9dfee26 100644 --- a/tests/artifacts/primitive-ops/contract.algo.ts +++ b/tests/artifacts/primitive-ops/contract.algo.ts @@ -1,4 +1,18 @@ -import { arc4, biguint, BigUint, Bytes, bytes, op, uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, biguint, BigUint, Bytes, bytes, log, op, uint64 } from '@algorandfoundation/algorand-typescript' +import { + Bool, + DynamicArray, + interpretAsArc4, + StaticArray, + Str, + Tuple, + UFixedNxM, + UintN, + UintN16, + UintN32, + UintN64, + UintN8, +} from '@algorandfoundation/algorand-typescript/arc4' export class PrimitiveOpsContract extends arc4.Contract { @arc4.abimethod() @@ -390,27 +404,26 @@ export class PrimitiveOpsContract extends arc4.Contract { return result } - // TODO: uncomment when arc4 types are available - // @arc4.abimethod - // public verify_log( # noqa: PLR0913 - // self, - // a: String, - // b: uint64, - // c: bytes, - // d: bytes, - // e: arc4.boolean, - // f: arc4.String, - // g: arc4.UIntN[typing.Literal[64]], - // h: arc4.BigUIntN[typing.Literal[256]], - // i: arc4.UFixedNxM[typing.Literal[32], typing.Literal[8]], - // j: arc4.BigUFixedNxM[typing.Literal[256], typing.Literal[16]], - // k: bytes, - // m: bytes, - // n: bytes, - // ) : None: - // d_biguint = BigUint(d) - // arc4_k = arc4.StaticArray[arc4.UInt8, typing.Literal[3]].from_bytes(k) - // arc4_m = arc4.DynamicArray[arc4.UInt16].from_bytes(m) - // arc4_n = arc4.Tuple[arc4.UInt32, arc4.uint64, arc4.String].from_bytes(n) - // log(a, b, c, d_biguint, e, f, g, h, i, j, arc4_k, arc4_m, arc4_n, sep="-") + @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, + ) { + const d_biguint = BigUint(d) + const arc4_k = interpretAsArc4>(k) + const arc4_m = interpretAsArc4>(m) + const arc4_n = interpretAsArc4>(n) + log(a, b, c, d_biguint, e, f, g, h, i, j, arc4_k, arc4_m, arc4_n) + } } diff --git a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal index 4e77e89..873741f 100644 --- a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal +++ b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.approval.teal @@ -9,30 +9,30 @@ tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.approvalPro // tests/artifacts/primitive-ops/contract.algo.ts::PrimitiveOpsContract.__puya_arc4_router__() -> uint64: __puya_arc4_router__: - // tests/artifacts/primitive-ops/contract.algo.ts:3 + // 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@59 - 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 // 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" + 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 + 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:4 + // tests/artifacts/primitive-ops/contract.algo.ts:5 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:4 + // tests/artifacts/primitive-ops/contract.algo.ts:5 // @arc4.abimethod() callsub verify_uint64_init itob @@ -44,20 +44,20 @@ __puya_arc4_router___verify_uint64_init_route@2: retsub __puya_arc4_router___verify_uint64_add_route@3: - // tests/artifacts/primitive-ops/contract.algo.ts:10 + // tests/artifacts/primitive-ops/contract.algo.ts:11 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:10 + // tests/artifacts/primitive-ops/contract.algo.ts:11 // @arc4.abimethod() callsub verify_uint64_add itob @@ -69,20 +69,20 @@ __puya_arc4_router___verify_uint64_add_route@3: retsub __puya_arc4_router___verify_uint64_sub_route@4: - // tests/artifacts/primitive-ops/contract.algo.ts:16 + // tests/artifacts/primitive-ops/contract.algo.ts:17 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:16 + // tests/artifacts/primitive-ops/contract.algo.ts:17 // @arc4.abimethod() callsub verify_uint64_sub itob @@ -94,20 +94,20 @@ __puya_arc4_router___verify_uint64_sub_route@4: retsub __puya_arc4_router___verify_uint64_mul_route@5: - // tests/artifacts/primitive-ops/contract.algo.ts:22 + // tests/artifacts/primitive-ops/contract.algo.ts:23 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:22 + // tests/artifacts/primitive-ops/contract.algo.ts:23 // @arc4.abimethod() callsub verify_uint64_mul itob @@ -119,20 +119,20 @@ __puya_arc4_router___verify_uint64_mul_route@5: retsub __puya_arc4_router___verify_uint64_div_route@6: - // tests/artifacts/primitive-ops/contract.algo.ts:28 + // tests/artifacts/primitive-ops/contract.algo.ts:29 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:28 + // tests/artifacts/primitive-ops/contract.algo.ts:29 // @arc4.abimethod() callsub verify_uint64_div itob @@ -144,20 +144,20 @@ __puya_arc4_router___verify_uint64_div_route@6: retsub __puya_arc4_router___verify_uint64_mod_route@7: - // tests/artifacts/primitive-ops/contract.algo.ts:34 + // tests/artifacts/primitive-ops/contract.algo.ts:35 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:34 + // tests/artifacts/primitive-ops/contract.algo.ts:35 // @arc4.abimethod() callsub verify_uint64_mod itob @@ -169,20 +169,20 @@ __puya_arc4_router___verify_uint64_mod_route@7: retsub __puya_arc4_router___verify_uint64_and_route@8: - // tests/artifacts/primitive-ops/contract.algo.ts:40 + // tests/artifacts/primitive-ops/contract.algo.ts:41 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:40 + // tests/artifacts/primitive-ops/contract.algo.ts:41 // @arc4.abimethod() callsub verify_uint64_and itob @@ -194,20 +194,20 @@ __puya_arc4_router___verify_uint64_and_route@8: retsub __puya_arc4_router___verify_uint64_or_route@9: - // tests/artifacts/primitive-ops/contract.algo.ts:46 + // tests/artifacts/primitive-ops/contract.algo.ts:47 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:46 + // tests/artifacts/primitive-ops/contract.algo.ts:47 // @arc4.abimethod() callsub verify_uint64_or itob @@ -219,20 +219,20 @@ __puya_arc4_router___verify_uint64_or_route@9: retsub __puya_arc4_router___verify_uint64_xor_route@10: - // tests/artifacts/primitive-ops/contract.algo.ts:52 + // tests/artifacts/primitive-ops/contract.algo.ts:53 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:52 + // tests/artifacts/primitive-ops/contract.algo.ts:53 // @arc4.abimethod() callsub verify_uint64_xor itob @@ -244,18 +244,18 @@ __puya_arc4_router___verify_uint64_xor_route@10: retsub __puya_arc4_router___verify_uint64_not_route@11: - // tests/artifacts/primitive-ops/contract.algo.ts:58 + // tests/artifacts/primitive-ops/contract.algo.ts:59 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:58 + // tests/artifacts/primitive-ops/contract.algo.ts:59 // @arc4.abimethod() callsub verify_uint64_not itob @@ -267,20 +267,20 @@ __puya_arc4_router___verify_uint64_not_route@11: retsub __puya_arc4_router___verify_uint64_lshift_route@12: - // tests/artifacts/primitive-ops/contract.algo.ts:64 + // tests/artifacts/primitive-ops/contract.algo.ts:65 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:64 + // tests/artifacts/primitive-ops/contract.algo.ts:65 // @arc4.abimethod() callsub verify_uint64_lshift itob @@ -292,20 +292,20 @@ __puya_arc4_router___verify_uint64_lshift_route@12: retsub __puya_arc4_router___verify_uint64_rshift_route@13: - // tests/artifacts/primitive-ops/contract.algo.ts:70 + // tests/artifacts/primitive-ops/contract.algo.ts:71 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:70 + // tests/artifacts/primitive-ops/contract.algo.ts:71 // @arc4.abimethod() callsub verify_uint64_rshift itob @@ -317,20 +317,20 @@ __puya_arc4_router___verify_uint64_rshift_route@13: retsub __puya_arc4_router___verify_uint64_pow_route@14: - // tests/artifacts/primitive-ops/contract.algo.ts:76 + // tests/artifacts/primitive-ops/contract.algo.ts:77 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:76 + // tests/artifacts/primitive-ops/contract.algo.ts:77 // @arc4.abimethod() callsub verify_uint64_pow itob @@ -342,20 +342,20 @@ __puya_arc4_router___verify_uint64_pow_route@14: retsub __puya_arc4_router___verify_uint64_eq_route@15: - // tests/artifacts/primitive-ops/contract.algo.ts:82 + // tests/artifacts/primitive-ops/contract.algo.ts:83 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:82 + // tests/artifacts/primitive-ops/contract.algo.ts:83 // @arc4.abimethod() callsub verify_uint64_eq bytec_1 // 0x00 @@ -370,20 +370,20 @@ __puya_arc4_router___verify_uint64_eq_route@15: retsub __puya_arc4_router___verify_uint64_ne_route@16: - // tests/artifacts/primitive-ops/contract.algo.ts:88 + // tests/artifacts/primitive-ops/contract.algo.ts:89 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:88 + // tests/artifacts/primitive-ops/contract.algo.ts:89 // @arc4.abimethod() callsub verify_uint64_ne bytec_1 // 0x00 @@ -398,20 +398,20 @@ __puya_arc4_router___verify_uint64_ne_route@16: retsub __puya_arc4_router___verify_uint64_lt_route@17: - // tests/artifacts/primitive-ops/contract.algo.ts:94 + // tests/artifacts/primitive-ops/contract.algo.ts:95 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:94 + // tests/artifacts/primitive-ops/contract.algo.ts:95 // @arc4.abimethod() callsub verify_uint64_lt bytec_1 // 0x00 @@ -426,20 +426,20 @@ __puya_arc4_router___verify_uint64_lt_route@17: retsub __puya_arc4_router___verify_uint64_le_route@18: - // tests/artifacts/primitive-ops/contract.algo.ts:100 + // tests/artifacts/primitive-ops/contract.algo.ts:101 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:100 + // tests/artifacts/primitive-ops/contract.algo.ts:101 // @arc4.abimethod() callsub verify_uint64_le bytec_1 // 0x00 @@ -454,20 +454,20 @@ __puya_arc4_router___verify_uint64_le_route@18: retsub __puya_arc4_router___verify_uint64_gt_route@19: - // tests/artifacts/primitive-ops/contract.algo.ts:106 + // tests/artifacts/primitive-ops/contract.algo.ts:107 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:106 + // tests/artifacts/primitive-ops/contract.algo.ts:107 // @arc4.abimethod() callsub verify_uint64_gt bytec_1 // 0x00 @@ -482,20 +482,20 @@ __puya_arc4_router___verify_uint64_gt_route@19: retsub __puya_arc4_router___verify_uint64_ge_route@20: - // tests/artifacts/primitive-ops/contract.algo.ts:112 + // tests/artifacts/primitive-ops/contract.algo.ts:113 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:112 + // tests/artifacts/primitive-ops/contract.algo.ts:113 // @arc4.abimethod() callsub verify_uint64_ge bytec_1 // 0x00 @@ -510,18 +510,18 @@ __puya_arc4_router___verify_uint64_ge_route@20: retsub __puya_arc4_router___verify_bytes_init_route@21: - // tests/artifacts/primitive-ops/contract.algo.ts:118 + // tests/artifacts/primitive-ops/contract.algo.ts:119 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:118 + // tests/artifacts/primitive-ops/contract.algo.ts:119 // @arc4.abimethod() callsub verify_bytes_init dup @@ -538,14 +538,14 @@ __puya_arc4_router___verify_bytes_init_route@21: retsub __puya_arc4_router___verify_bytes_add_route@22: - // tests/artifacts/primitive-ops/contract.algo.ts:124 + // tests/artifacts/primitive-ops/contract.algo.ts:125 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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 @@ -555,7 +555,7 @@ __puya_arc4_router___verify_bytes_add_route@22: btoi txna ApplicationArgs 4 btoi - // tests/artifacts/primitive-ops/contract.algo.ts:124 + // tests/artifacts/primitive-ops/contract.algo.ts:125 // @arc4.abimethod() callsub verify_bytes_add dup @@ -572,20 +572,20 @@ __puya_arc4_router___verify_bytes_add_route@22: retsub __puya_arc4_router___verify_bytes_eq_route@23: - // tests/artifacts/primitive-ops/contract.algo.ts:133 + // tests/artifacts/primitive-ops/contract.algo.ts:134 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:133 + // tests/artifacts/primitive-ops/contract.algo.ts:134 // @arc4.abimethod() callsub verify_bytes_eq bytec_1 // 0x00 @@ -600,20 +600,20 @@ __puya_arc4_router___verify_bytes_eq_route@23: retsub __puya_arc4_router___verify_bytes_ne_route@24: - // tests/artifacts/primitive-ops/contract.algo.ts:139 + // tests/artifacts/primitive-ops/contract.algo.ts:140 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:139 + // tests/artifacts/primitive-ops/contract.algo.ts:140 // @arc4.abimethod() callsub verify_bytes_ne bytec_1 // 0x00 @@ -628,20 +628,20 @@ __puya_arc4_router___verify_bytes_ne_route@24: retsub __puya_arc4_router___verify_bytes_and_route@25: - // tests/artifacts/primitive-ops/contract.algo.ts:145 + // tests/artifacts/primitive-ops/contract.algo.ts:146 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:145 + // tests/artifacts/primitive-ops/contract.algo.ts:146 // @arc4.abimethod() callsub verify_bytes_and dup @@ -658,20 +658,20 @@ __puya_arc4_router___verify_bytes_and_route@25: retsub __puya_arc4_router___verify_bytes_or_route@26: - // tests/artifacts/primitive-ops/contract.algo.ts:151 + // tests/artifacts/primitive-ops/contract.algo.ts:152 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:151 + // tests/artifacts/primitive-ops/contract.algo.ts:152 // @arc4.abimethod() callsub verify_bytes_or dup @@ -688,20 +688,20 @@ __puya_arc4_router___verify_bytes_or_route@26: retsub __puya_arc4_router___verify_bytes_xor_route@27: - // tests/artifacts/primitive-ops/contract.algo.ts:157 + // tests/artifacts/primitive-ops/contract.algo.ts:158 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:157 + // tests/artifacts/primitive-ops/contract.algo.ts:158 // @arc4.abimethod() callsub verify_bytes_xor dup @@ -718,20 +718,20 @@ __puya_arc4_router___verify_bytes_xor_route@27: retsub __puya_arc4_router___verify_bytes_not_route@28: - // tests/artifacts/primitive-ops/contract.algo.ts:163 + // tests/artifacts/primitive-ops/contract.algo.ts:164 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:163 + // tests/artifacts/primitive-ops/contract.algo.ts:164 // @arc4.abimethod() callsub verify_bytes_not dup @@ -748,20 +748,20 @@ __puya_arc4_router___verify_bytes_not_route@28: retsub __puya_arc4_router___verify_biguint_add_route@29: - // tests/artifacts/primitive-ops/contract.algo.ts:171 + // tests/artifacts/primitive-ops/contract.algo.ts:172 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:171 + // tests/artifacts/primitive-ops/contract.algo.ts:172 // @arc4.abimethod() callsub verify_biguint_add dup @@ -778,20 +778,20 @@ __puya_arc4_router___verify_biguint_add_route@29: retsub __puya_arc4_router___verify_biguint_add_uint64_route@30: - // tests/artifacts/primitive-ops/contract.algo.ts:179 + // tests/artifacts/primitive-ops/contract.algo.ts:180 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:179 + // tests/artifacts/primitive-ops/contract.algo.ts:180 // @arc4.abimethod() callsub verify_biguint_add_uint64 dup @@ -808,20 +808,20 @@ __puya_arc4_router___verify_biguint_add_uint64_route@30: retsub __puya_arc4_router___verify_biguint_sub_route@31: - // tests/artifacts/primitive-ops/contract.algo.ts:187 + // tests/artifacts/primitive-ops/contract.algo.ts:188 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:187 + // tests/artifacts/primitive-ops/contract.algo.ts:188 // @arc4.abimethod() callsub verify_biguint_sub dup @@ -838,20 +838,20 @@ __puya_arc4_router___verify_biguint_sub_route@31: retsub __puya_arc4_router___verify_biguint_sub_uint64_route@32: - // tests/artifacts/primitive-ops/contract.algo.ts:195 + // tests/artifacts/primitive-ops/contract.algo.ts:196 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:195 + // tests/artifacts/primitive-ops/contract.algo.ts:196 // @arc4.abimethod() callsub verify_biguint_sub_uint64 dup @@ -868,20 +868,20 @@ __puya_arc4_router___verify_biguint_sub_uint64_route@32: retsub __puya_arc4_router___verify_biguint_mul_route@33: - // tests/artifacts/primitive-ops/contract.algo.ts:203 + // tests/artifacts/primitive-ops/contract.algo.ts:204 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:203 + // tests/artifacts/primitive-ops/contract.algo.ts:204 // @arc4.abimethod() callsub verify_biguint_mul dup @@ -898,20 +898,20 @@ __puya_arc4_router___verify_biguint_mul_route@33: retsub __puya_arc4_router___verify_biguint_mul_uint64_route@34: - // tests/artifacts/primitive-ops/contract.algo.ts:211 + // tests/artifacts/primitive-ops/contract.algo.ts:212 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:211 + // tests/artifacts/primitive-ops/contract.algo.ts:212 // @arc4.abimethod() callsub verify_biguint_mul_uint64 dup @@ -928,20 +928,20 @@ __puya_arc4_router___verify_biguint_mul_uint64_route@34: retsub __puya_arc4_router___verify_biguint_div_route@35: - // tests/artifacts/primitive-ops/contract.algo.ts:219 + // tests/artifacts/primitive-ops/contract.algo.ts:220 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:219 + // tests/artifacts/primitive-ops/contract.algo.ts:220 // @arc4.abimethod() callsub verify_biguint_div dup @@ -958,20 +958,20 @@ __puya_arc4_router___verify_biguint_div_route@35: retsub __puya_arc4_router___verify_biguint_div_uint64_route@36: - // tests/artifacts/primitive-ops/contract.algo.ts:227 + // tests/artifacts/primitive-ops/contract.algo.ts:228 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:227 + // tests/artifacts/primitive-ops/contract.algo.ts:228 // @arc4.abimethod() callsub verify_biguint_div_uint64 dup @@ -988,20 +988,20 @@ __puya_arc4_router___verify_biguint_div_uint64_route@36: retsub __puya_arc4_router___verify_biguint_mod_route@37: - // tests/artifacts/primitive-ops/contract.algo.ts:235 + // tests/artifacts/primitive-ops/contract.algo.ts:236 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:235 + // tests/artifacts/primitive-ops/contract.algo.ts:236 // @arc4.abimethod() callsub verify_biguint_mod dup @@ -1018,20 +1018,20 @@ __puya_arc4_router___verify_biguint_mod_route@37: retsub __puya_arc4_router___verify_biguint_mod_uint64_route@38: - // tests/artifacts/primitive-ops/contract.algo.ts:243 + // tests/artifacts/primitive-ops/contract.algo.ts:244 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:243 + // tests/artifacts/primitive-ops/contract.algo.ts:244 // @arc4.abimethod() callsub verify_biguint_mod_uint64 dup @@ -1048,20 +1048,20 @@ __puya_arc4_router___verify_biguint_mod_uint64_route@38: retsub __puya_arc4_router___verify_biguint_and_route@39: - // tests/artifacts/primitive-ops/contract.algo.ts:251 + // tests/artifacts/primitive-ops/contract.algo.ts:252 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:251 + // tests/artifacts/primitive-ops/contract.algo.ts:252 // @arc4.abimethod() callsub verify_biguint_and dup @@ -1078,20 +1078,20 @@ __puya_arc4_router___verify_biguint_and_route@39: retsub __puya_arc4_router___verify_biguint_and_uint64_route@40: - // tests/artifacts/primitive-ops/contract.algo.ts:259 + // tests/artifacts/primitive-ops/contract.algo.ts:260 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:259 + // tests/artifacts/primitive-ops/contract.algo.ts:260 // @arc4.abimethod() callsub verify_biguint_and_uint64 dup @@ -1108,20 +1108,20 @@ __puya_arc4_router___verify_biguint_and_uint64_route@40: retsub __puya_arc4_router___verify_biguint_or_route@41: - // tests/artifacts/primitive-ops/contract.algo.ts:267 + // tests/artifacts/primitive-ops/contract.algo.ts:268 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:267 + // tests/artifacts/primitive-ops/contract.algo.ts:268 // @arc4.abimethod() callsub verify_biguint_or dup @@ -1138,20 +1138,20 @@ __puya_arc4_router___verify_biguint_or_route@41: retsub __puya_arc4_router___verify_biguint_or_uint64_route@42: - // tests/artifacts/primitive-ops/contract.algo.ts:275 + // tests/artifacts/primitive-ops/contract.algo.ts:276 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:275 + // tests/artifacts/primitive-ops/contract.algo.ts:276 // @arc4.abimethod() callsub verify_biguint_or_uint64 dup @@ -1168,20 +1168,20 @@ __puya_arc4_router___verify_biguint_or_uint64_route@42: retsub __puya_arc4_router___verify_biguint_xor_route@43: - // tests/artifacts/primitive-ops/contract.algo.ts:283 + // tests/artifacts/primitive-ops/contract.algo.ts:284 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:283 + // tests/artifacts/primitive-ops/contract.algo.ts:284 // @arc4.abimethod() callsub verify_biguint_xor dup @@ -1198,20 +1198,20 @@ __puya_arc4_router___verify_biguint_xor_route@43: retsub __puya_arc4_router___verify_biguint_xor_uint64_route@44: - // tests/artifacts/primitive-ops/contract.algo.ts:291 + // tests/artifacts/primitive-ops/contract.algo.ts:292 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:291 + // tests/artifacts/primitive-ops/contract.algo.ts:292 // @arc4.abimethod() callsub verify_biguint_xor_uint64 dup @@ -1228,20 +1228,20 @@ __puya_arc4_router___verify_biguint_xor_uint64_route@44: retsub __puya_arc4_router___verify_biguint_eq_route@45: - // tests/artifacts/primitive-ops/contract.algo.ts:299 + // tests/artifacts/primitive-ops/contract.algo.ts:300 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:299 + // tests/artifacts/primitive-ops/contract.algo.ts:300 // @arc4.abimethod() callsub verify_biguint_eq bytec_1 // 0x00 @@ -1256,20 +1256,20 @@ __puya_arc4_router___verify_biguint_eq_route@45: retsub __puya_arc4_router___verify_biguint_eq_uint64_route@46: - // tests/artifacts/primitive-ops/contract.algo.ts:307 + // tests/artifacts/primitive-ops/contract.algo.ts:308 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:307 + // tests/artifacts/primitive-ops/contract.algo.ts:308 // @arc4.abimethod() callsub verify_biguint_eq_uint64 bytec_1 // 0x00 @@ -1284,20 +1284,20 @@ __puya_arc4_router___verify_biguint_eq_uint64_route@46: retsub __puya_arc4_router___verify_biguint_ne_route@47: - // tests/artifacts/primitive-ops/contract.algo.ts:314 + // tests/artifacts/primitive-ops/contract.algo.ts:315 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:314 + // tests/artifacts/primitive-ops/contract.algo.ts:315 // @arc4.abimethod() callsub verify_biguint_ne bytec_1 // 0x00 @@ -1312,20 +1312,20 @@ __puya_arc4_router___verify_biguint_ne_route@47: retsub __puya_arc4_router___verify_biguint_ne_uint64_route@48: - // tests/artifacts/primitive-ops/contract.algo.ts:322 + // tests/artifacts/primitive-ops/contract.algo.ts:323 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:322 + // tests/artifacts/primitive-ops/contract.algo.ts:323 // @arc4.abimethod() callsub verify_biguint_ne_uint64 bytec_1 // 0x00 @@ -1340,20 +1340,20 @@ __puya_arc4_router___verify_biguint_ne_uint64_route@48: retsub __puya_arc4_router___verify_biguint_lt_route@49: - // tests/artifacts/primitive-ops/contract.algo.ts:329 + // tests/artifacts/primitive-ops/contract.algo.ts:330 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:329 + // tests/artifacts/primitive-ops/contract.algo.ts:330 // @arc4.abimethod() callsub verify_biguint_lt bytec_1 // 0x00 @@ -1368,20 +1368,20 @@ __puya_arc4_router___verify_biguint_lt_route@49: retsub __puya_arc4_router___verify_biguint_lt_uint64_route@50: - // tests/artifacts/primitive-ops/contract.algo.ts:337 + // tests/artifacts/primitive-ops/contract.algo.ts:338 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:337 + // tests/artifacts/primitive-ops/contract.algo.ts:338 // @arc4.abimethod() callsub verify_biguint_lt_uint64 bytec_1 // 0x00 @@ -1396,20 +1396,20 @@ __puya_arc4_router___verify_biguint_lt_uint64_route@50: retsub __puya_arc4_router___verify_biguint_le_route@51: - // tests/artifacts/primitive-ops/contract.algo.ts:345 + // tests/artifacts/primitive-ops/contract.algo.ts:346 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:345 + // tests/artifacts/primitive-ops/contract.algo.ts:346 // @arc4.abimethod() callsub verify_biguint_le bytec_1 // 0x00 @@ -1424,20 +1424,20 @@ __puya_arc4_router___verify_biguint_le_route@51: retsub __puya_arc4_router___verify_biguint_le_uint64_route@52: - // tests/artifacts/primitive-ops/contract.algo.ts:353 + // tests/artifacts/primitive-ops/contract.algo.ts:354 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:353 + // tests/artifacts/primitive-ops/contract.algo.ts:354 // @arc4.abimethod() callsub verify_biguint_le_uint64 bytec_1 // 0x00 @@ -1452,20 +1452,20 @@ __puya_arc4_router___verify_biguint_le_uint64_route@52: retsub __puya_arc4_router___verify_biguint_gt_route@53: - // tests/artifacts/primitive-ops/contract.algo.ts:361 + // tests/artifacts/primitive-ops/contract.algo.ts:362 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:361 + // tests/artifacts/primitive-ops/contract.algo.ts:362 // @arc4.abimethod() callsub verify_biguint_gt bytec_1 // 0x00 @@ -1480,20 +1480,20 @@ __puya_arc4_router___verify_biguint_gt_route@53: retsub __puya_arc4_router___verify_biguint_gt_uint64_route@54: - // tests/artifacts/primitive-ops/contract.algo.ts:369 + // tests/artifacts/primitive-ops/contract.algo.ts:370 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:369 + // tests/artifacts/primitive-ops/contract.algo.ts:370 // @arc4.abimethod() callsub verify_biguint_gt_uint64 bytec_1 // 0x00 @@ -1508,20 +1508,20 @@ __puya_arc4_router___verify_biguint_gt_uint64_route@54: retsub __puya_arc4_router___verify_biguint_ge_route@55: - // tests/artifacts/primitive-ops/contract.algo.ts:377 + // tests/artifacts/primitive-ops/contract.algo.ts:378 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:377 + // tests/artifacts/primitive-ops/contract.algo.ts:378 // @arc4.abimethod() callsub verify_biguint_ge bytec_1 // 0x00 @@ -1536,20 +1536,20 @@ __puya_arc4_router___verify_biguint_ge_route@55: retsub __puya_arc4_router___verify_biguint_ge_uint64_route@56: - // tests/artifacts/primitive-ops/contract.algo.ts:385 + // tests/artifacts/primitive-ops/contract.algo.ts:386 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/primitive-ops/contract.algo.ts:3 + 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:385 + // tests/artifacts/primitive-ops/contract.algo.ts:386 // @arc4.abimethod() callsub verify_biguint_ge_uint64 bytec_1 // 0x00 @@ -1563,19 +1563,55 @@ __puya_arc4_router___verify_biguint_ge_uint64_route@56: intc_0 // 1 retsub -__puya_arc4_router___bare_routing@59: - // tests/artifacts/primitive-ops/contract.algo.ts:3 +__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@63 + bnz __puya_arc4_router___after_if_else@64 txn ApplicationID ! - assert // is creating + assert // can only call when creating intc_0 // 1 retsub -__puya_arc4_router___after_if_else@63: - // tests/artifacts/primitive-ops/contract.algo.ts:3 +__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 @@ -1583,937 +1619,990 @@ __puya_arc4_router___after_if_else@63: // 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:4-5 + // 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:6 + // 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:7 + // 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:10-11 + // 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:12 + // 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:13 + // 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:16-17 + // 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:18 + // 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:19 + // 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:22-23 + // 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:24 + // 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:25 + // 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:28-29 + // 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:30 + // 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:31 + // 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:34-35 + // 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:36 + // 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:37 + // 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:40-41 + // 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:42 + // 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:43 + // 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:46-47 + // 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:48 + // 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:49 + // 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:52-53 + // 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:54 + // 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:55 + // 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:58-59 + // 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:60 + // tests/artifacts/primitive-ops/contract.algo.ts:61 // const result: uint64 = ~a frame_dig -1 ~ - // tests/artifacts/primitive-ops/contract.algo.ts:61 + // 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:64-65 + // 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:66 + // 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:67 + // 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:70-71 + // 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:72 + // 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:73 + // 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:76-77 + // 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:78 + // 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:79 + // 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:82-83 + // 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:84 + // 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:85 + // 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:88-89 + // 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:90 + // 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:91 + // 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:94-95 + // 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:96 + // 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:97 + // 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:100-101 + // 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:102 + // 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:103 + // 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:106-107 + // 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:108 + // 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:109 + // 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:112-113 + // 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:114 + // 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:115 + // 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:118-119 + // 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:120 + // 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:121 + // 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:124-125 + // 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:126 + // 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:127 + // 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:128 + // tests/artifacts/primitive-ops/contract.algo.ts:129 // const result = paddedA.concat(paddedB) concat - // tests/artifacts/primitive-ops/contract.algo.ts:129 + // tests/artifacts/primitive-ops/contract.algo.ts:130 // const resultHash = op.sha256(result) sha256 - // tests/artifacts/primitive-ops/contract.algo.ts:130 + // 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:133-134 + // 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:135 + // 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:136 + // 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:139-140 + // 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:141 + // 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:142 + // 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:145-146 + // 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:147 + // 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:148 + // 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:151-152 + // 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:153 + // 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:154 + // 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:157-158 + // 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:159 + // 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:160 + // 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:163-164 + // 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:165 + // 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:166 + // tests/artifacts/primitive-ops/contract.algo.ts:167 // const result = paddedA.bitwiseInvert() b~ - // tests/artifacts/primitive-ops/contract.algo.ts:167 + // tests/artifacts/primitive-ops/contract.algo.ts:168 // const resultHash = op.sha256(result) sha256 - // tests/artifacts/primitive-ops/contract.algo.ts:168 + // 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:171-172 + // 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:175 + // 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:176 + // 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:179-180 + // 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:182 + // tests/artifacts/primitive-ops/contract.algo.ts:183 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:183 + // 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:184 + // 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:187-188 + // 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:191 + // 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:192 + // 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:195-196 + // 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:198 + // tests/artifacts/primitive-ops/contract.algo.ts:199 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:199 + // 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:200 + // 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:203-204 + // 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:207 + // 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:208 + // 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:211-212 + // 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:214 + // tests/artifacts/primitive-ops/contract.algo.ts:215 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:215 + // 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:216 + // 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:219-220 + // 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:223 + // 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:224 + // 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:227-228 + // 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:230 + // tests/artifacts/primitive-ops/contract.algo.ts:231 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:231 + // 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:232 + // 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:235-236 + // 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:239 + // 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:240 + // 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:243-244 + // 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:246 + // tests/artifacts/primitive-ops/contract.algo.ts:247 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:247 + // 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:248 + // 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:251-252 + // 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:255 + // 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:256 + // 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:259-260 + // 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:262 + // tests/artifacts/primitive-ops/contract.algo.ts:263 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:263 + // 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:264 + // 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:267-268 + // 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:271 + // 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:272 + // 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:275-276 + // 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:278 + // tests/artifacts/primitive-ops/contract.algo.ts:279 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:279 + // 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:280 + // 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:283-284 + // 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:287 + // 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:288 + // 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:291-292 + // 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:294 + // tests/artifacts/primitive-ops/contract.algo.ts:295 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:295 + // 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:296 + // 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:299-300 + // 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:303 + // 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:304 + // 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:307-308 + // 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:310 + // 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:311 + // 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:314-315 + // 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:318 + // 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:319 + // 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:322-323 + // 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:325 + // 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:326 + // 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:329-330 + // 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:333 + // 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:334 + // 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:337-338 + // 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:340 + // tests/artifacts/primitive-ops/contract.algo.ts:341 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:341 + // 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:342 + // 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:345-346 + // 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:349 + // 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:350 + // 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:353-354 + // 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:356 + // tests/artifacts/primitive-ops/contract.algo.ts:357 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:357 + // 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:358 + // 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:361-362 + // 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:365 + // 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:366 + // 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:369-370 + // 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:372 + // tests/artifacts/primitive-ops/contract.algo.ts:373 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:373 + // 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:374 + // 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:377-378 + // 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:381 + // 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:382 + // 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:385-386 + // 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:388 + // tests/artifacts/primitive-ops/contract.algo.ts:389 // const b_biguint = BigUint(b) frame_dig -1 itob - // tests/artifacts/primitive-ops/contract.algo.ts:389 + // 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:390 + // 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 index 26d987d..8649c5e 100644 --- a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json +++ b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json @@ -274,10 +274,15 @@ "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": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUgMHgwMAogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OQogICAgcHVzaGJ5dGVzcyAweDcyNWM2OTJiIDB4MTczMTQ1NTkgMHg1M2YzNDg5MyAweDg4YzhiMjY5IDB4YTQ2NGI3YWIgMHg5YzhiMTFiOCAweDZmNDA2NTRlIDB4ZWM5YTI5NzQgMHhjNzkzNzA4ZiAweDdkZGI3NDk5IDB4YTIxYzQ0M2QgMHg2ZTdmYjIxMiAweGIwMDdmY2IwIDB4MmViYzIwZDQgMHhiMDk1NGI2NiAweGRkMTQwYWVmIDB4YWNlNDc0ZGEgMHhiYTY5NDk5MCAweDZkYjU4MWMwIDB4OTFjOGRiODkgMHhkYmU3NzE1OCAweDlhMGYyMmUxIDB4NjQwMzNkMzcgMHgyYTcyMzdjNSAweGUzYTk0NDU4IDB4NDJmODdmN2QgMHgyYjU1NDJhNCAweDliZTJmYmU5IDB4MWNkOTI1MTUgMHg2NGUxNzA1YyAweGYxMjcxYzUwIDB4MmFiNjNiNzAgMHg4MzRiYjdkMiAweDUzMTYyMGQ3IDB4M2ZiOWU3NjkgMHhmYThkYjBiYyAweGE3MmVhNDg1IDB4YjdiMGJhMTkgMHg3NDQ2MGM0MiAweGFiMzIwNzM4IDB4NTJhZDQ2NTQgMHgxMDE1NjM5OSAweDBmMDc1OTU3IDB4YmQ4NDNkZmYgMHhiMzc3ZDM4MSAweDg5NzY3MjY1IDB4NDU2YjRiMjMgMHgzM2QxYjg4YyAweDZiZjk3M2VhIDB4NjdjZDZiYjIgMHgzZjU4ODA1YSAweDFlMTMwMDM5IDB4NTA5ZGM5MWQgMHhhNTY0YTIwMiAweDIzNjUwNzYzIC8vIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9pbml0KGJ5dGVbXSl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfYWRkKHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X3N1Yih1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9tdWwodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfZGl2KHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X21vZCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9hbmQodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfb3IodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfeG9yKHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X25vdCh1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2xzaGlmdCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9yc2hpZnQodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV91aW50NjRfcG93KHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2VxKHVpbnQ2NCx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9uZSh1aW50NjQsdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50NjRfbHQodWludDY0LHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2xlKHVpbnQ2NCx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9ndCh1aW50NjQsdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50NjRfZ2UodWludDY0LHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfaW5pdCh1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfYWRkKGJ5dGVbXSxieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9ieXRlc19lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlc19uZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlc19hbmQoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9ieXRlc19vcihieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX3hvcihieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX25vdChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfYWRkKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9hZGRfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9zdWIoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X211bChieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZGl2KGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9kaXZfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9tb2QoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X21vZF91aW50NjQoYnl0ZVtdLHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2FuZChieXRlW10sYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfb3IoYnl0ZVtdLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfeG9yKGJ5dGVbXSxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF94b3JfdWludDY0KGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfbHQoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9sdF91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2xlX3VpbnQ2NChieXRlW10sdWludDY0KWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50X2d0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0KGJ5dGVbXSx1aW50NjQpYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRfZ2UoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludF9nZV91aW50NjQoYnl0ZVtdLHVpbnQ2NClib29sIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9pbml0X3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9hZGRfcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X3N1Yl9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbXVsX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9kaXZfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X21vZF9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYW5kX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9vcl9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfeG9yX3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbm90X3JvdXRlQDExIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbHNoaWZ0X3JvdXRlQDEyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfcnNoaWZ0X3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfcG93X3JvdXRlQDE0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZXFfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9uZV9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2x0X3JvdXRlQDE3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbGVfcm91dGVAMTggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9ndF9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2dlX3JvdXRlQDIwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19pbml0X3JvdXRlQDIxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19hZGRfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2VxX3JvdXRlQDIzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19uZV9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfYW5kX3JvdXRlQDI1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19vcl9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfeG9yX3JvdXRlQDI3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19ub3Rfcm91dGVAMjggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYWRkX3JvdXRlQDI5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2FkZF91aW50NjRfcm91dGVAMzAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfc3ViX3JvdXRlQDMxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjRfcm91dGVAMzIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbXVsX3JvdXRlQDMzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X211bF91aW50NjRfcm91dGVAMzQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZGl2X3JvdXRlQDM1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjRfcm91dGVAMzYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbW9kX3JvdXRlQDM3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X21vZF91aW50NjRfcm91dGVAMzggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYW5kX3JvdXRlQDM5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2FuZF91aW50NjRfcm91dGVANDAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfb3Jfcm91dGVANDEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfb3JfdWludDY0X3JvdXRlQDQyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3hvcl9yb3V0ZUA0MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF94b3JfdWludDY0X3JvdXRlQDQ0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2VxX3JvdXRlQDQ1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NF9yb3V0ZUA0NiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9uZV9yb3V0ZUA0NyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9uZV91aW50NjRfcm91dGVANDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbHRfcm91dGVANDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0X3JvdXRlQDUwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2xlX3JvdXRlQDUxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2xlX3VpbnQ2NF9yb3V0ZUA1MiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9ndF9yb3V0ZUA1MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9ndF91aW50NjRfcm91dGVANTQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ2Vfcm91dGVANTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0X3JvdXRlQDU2CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2luaXRfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2luaXQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYWRkX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfYWRkCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X3N1Yl9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X3N1YgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9tdWxfcm91dGVANToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9tdWwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZGl2X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfZGl2CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X21vZF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X21vZAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9hbmRfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9hbmQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfb3Jfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9vcgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF94b3Jfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfeG9yCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X25vdF9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9ub3QKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbHNoaWZ0X3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X2xzaGlmdAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9yc2hpZnRfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfcnNoaWZ0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X3Bvd19yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9wb3cKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZXFfcm91dGVAMTU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X25lX3JvdXRlQDE2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludDY0X25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9sdF9yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfbGVfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZ3Rfcm91dGVAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfZ2Vfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19pbml0X3JvdXRlQDIxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19pbml0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2FkZF9yb3V0ZUAyMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19hZGQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfZXFfcm91dGVAMjM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbmVfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfYW5kX3JvdXRlQDI1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2FuZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19vcl9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlc19vcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc194b3Jfcm91dGVAMjc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfeG9yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX25vdF9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX25vdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2FkZF9yb3V0ZUAyOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FkZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2FkZF91aW50NjRfcm91dGVAMzA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9zdWJfcm91dGVAMzE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9zdWIKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9zdWJfdWludDY0X3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9zdWJfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbXVsX3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbXVsCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NF9yb3V0ZUAzNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2Rpdl9yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2RpdgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjRfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9tb2Rfcm91dGVAMzc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tb2QKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9tb2RfdWludDY0X3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9tb2RfdWludDY0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYW5kX3JvdXRlQDM5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfYW5kCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NF9yb3V0ZUA0MDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X29yX3JvdXRlQDQxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRfb3IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9vcl91aW50NjRfcm91dGVANDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3hvcl9yb3V0ZUA0MzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X3hvcgogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50X3hvcl91aW50NjRfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9lcV9yb3V0ZUA0NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0X3JvdXRlQDQ2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9lcV91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9uZV9yb3V0ZUA0NzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbmVfdWludDY0X3JvdXRlQDQ4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9uZV91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sdF9yb3V0ZUA0OToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0X3JvdXRlQDUwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sdF91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9sZV9yb3V0ZUA1MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0X3JvdXRlQDUyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9sZV91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9ndF9yb3V0ZUA1MzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0X3JvdXRlQDU0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9ndF91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludF9nZV9yb3V0ZUA1NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgUHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50X2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0X3JvdXRlQDU2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludF9nZV91aW50NjQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18xIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjMKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfaW5pdChyYXdfdmFsdWU6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NC01CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfaW5pdChyYXdfdmFsdWU6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5idG9pKHJhd192YWx1ZSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2FkZChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAtMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9hZGQoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyCiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgKyBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgKwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9zdWIoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9zdWI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2LTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfc3ViKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOAogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhIC0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIC0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbXVsKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbXVsOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMi0yMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X211bChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAqIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2RpdihhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2RpdjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgtMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9kaXYoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwCiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgLyBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgLwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9tb2QoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9tb2Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0LTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbW9kKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNgogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhICUgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfYW5kKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfYW5kOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0MC00MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X2FuZChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAmIGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAmCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X29yKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfb3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2LTQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfb3IoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4CiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgfCBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgfAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF94b3IoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF94b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUyLTUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfeG9yKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhIF4gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIF4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfbm90KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X25vdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgtNTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9ub3QoYTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2MAogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSB+YQogICAgZnJhbWVfZGlnIC0xCiAgICB+CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2xzaGlmdChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2xzaGlmdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjQtNjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9sc2hpZnQoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2CiAgICAvLyBjb25zdCByZXN1bHQ6IHVpbnQ2NCA9IGEgPDwgYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNobAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9yc2hpZnQoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnQ2NF9yc2hpZnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcwLTcxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfcnNoaWZ0KGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3MgogICAgLy8gY29uc3QgcmVzdWx0OiB1aW50NjQgPSBhID4+IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfcG93KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfcG93OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3Ni03NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludDY0X3BvdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgKICAgIC8vIGNvbnN0IHJlc3VsdDogdWludDY0ID0gYSAqKiBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXhwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2VxKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyLTgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfZXEoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NAogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA9PT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID09CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X25lKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg4LTg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbmUoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5MAogICAgLy8gY29uc3QgcmVzdWx0ID0gYSAhPT0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2x0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk0LTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfbHQoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5NgogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA8IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2xlKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMC0xMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9sZShhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMgogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA8PSBiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPD0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludDY0X2d0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNi0xMDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9ndChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOAogICAgLy8gY29uc3QgcmVzdWx0ID0gYSA+IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA+CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9nZShhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTItMTEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfZ2UoYTogdWludDY0LCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgPj0gYgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgID49CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2luaXQocmF3X3ZhbHVlOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZXNfaW5pdDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE4LTExOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfaW5pdChyYXdfdmFsdWU6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLml0b2IocmF3X3ZhbHVlKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2FkZChhOiBieXRlcywgYjogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCwgcGFkX2Jfc2l6ZTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI0LTEyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfYWRkKGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byA0IDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX2Ffc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjcKICAgIC8vIGNvbnN0IHBhZGRlZEIgPSBvcC5iemVybyhwYWRfYl9zaXplKS5jb25jYXQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOAogICAgLy8gY29uc3QgcmVzdWx0ID0gcGFkZGVkQS5jb25jYXQocGFkZGVkQikKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjkKICAgIC8vIGNvbnN0IHJlc3VsdEhhc2ggPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMAogICAgLy8gcmV0dXJuIHJlc3VsdEhhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVzX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzMtMTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlc19lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzUKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgPT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVzX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzktMTQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlc19uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEgIT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19hbmQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX2FuZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ1LTE0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfYW5kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEuYml0d2lzZUFuZChiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX29yKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc19vcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUxLTE1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfb3IoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MwogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5iaXR3aXNlT3IoYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc194b3IoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2J5dGVzX3hvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3LTE1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfeG9yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTkKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGEuYml0d2lzZVhvcihiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX25vdChhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlc19ub3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2My0xNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVzX25vdChhOiBieXRlcywgcGFkX3NpemU6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IHBhZGRlZEEuYml0d2lzZUludmVydCgpCiAgICBifgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjcKICAgIC8vIGNvbnN0IHJlc3VsdEhhc2ggPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OAogICAgLy8gcmV0dXJuIHJlc3VsdEhhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9hZGQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MS0xNzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYWRkKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzUKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCArIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3NgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2FkZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OS0xODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYWRkX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MgogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MwogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICsgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGIrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3N1YihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9zdWI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4Ny0xODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfc3ViKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTEKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAtIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGItCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X3N1Yl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NS0xOTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfc3ViX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5OAogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5OQogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IC0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGItCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X211bChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tdWw6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMy0yMDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbXVsKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDcKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAqIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwOAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X211bF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X211bF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMS0yMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbXVsX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNAogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNQogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICogYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGIqCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2RpdihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9kaXY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxOS0yMjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZGl2KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjMKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAvIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2Rpdl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNy0yMjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZGl2X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMAogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMQogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IC8gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGIvCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X21vZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9tb2Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNS0yMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbW9kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzkKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAlIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X21vZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X21vZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0My0yNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbW9kX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NgogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NwogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICUgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGIlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0OAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FuZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF9hbmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MS0yNTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYW5kKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTUKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCAmIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1NgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X2FuZF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1OS0yNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfYW5kX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MgogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MwogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50ICYgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGImCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X29yKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X29yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjctMjY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X29yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzEKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCB8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRfb3JfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzUtMjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X29yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3OAogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3OQogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IHwgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3hvcihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludF94b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4My0yODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfeG9yKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODcKICAgIC8vIGNvbnN0IHJlc3VsdDogYmlndWludCA9IGFfYmlndWludCBeIGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1aW50X3hvcl91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MS0yOTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfeG9yX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NAogICAgLy8gY29uc3QgYl9iaWd1aW50ID0gQmlnVWludChiKQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NQogICAgLy8gY29uc3QgcmVzdWx0OiBiaWd1aW50ID0gYV9iaWd1aW50IF4gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGJeCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk5LTMwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDMKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA9PT0gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYj09CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfZXFfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDctMzA4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2VxX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEwCiAgICAvLyBjb25zdCByZXN1bHQgPSBhX2JpZ3VpbnQgPT09IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgZnJhbWVfZGlnIC0yCiAgICBiPT0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRfbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNC0zMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE4CiAgICAvLyBjb25zdCByZXN1bHQgPSBhX2JpZ3VpbnQgIT09IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGIhPQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X25lX3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIyLTMyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9uZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNQogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50ICE9PSBCaWdVaW50KGIpCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGZyYW1lX2RpZyAtMgogICAgYiE9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjktMzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMwogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50IDwgYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYjwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sdF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNy0zMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbHRfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDAKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBiPgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQ1LTM0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDkKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiPD0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9sZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9sZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1My0zNTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfbGVfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTYKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNTcKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA8PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgYj49CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50X2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNjEtMzYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50X2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2NQogICAgLy8gY29uc3QgcmVzdWx0ID0gYV9iaWd1aW50ID4gYl9iaWd1aW50CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYj4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9ndF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9ndF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2OS0zNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZ3RfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzIKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzMKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+IGJfYmlndWludAogICAgZnJhbWVfZGlnIC0yCiAgICBiPAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNzQKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50X2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc3LTM3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludF9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODEKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiPj0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzgyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludF9nZV91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludF9nZV91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4NS0zODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRfZ2VfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODgKICAgIC8vIGNvbnN0IGJfYmlndWludCA9IEJpZ1VpbnQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3ByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozODkKICAgIC8vIGNvbnN0IHJlc3VsdCA9IGFfYmlndWludCA+PSBiX2JpZ3VpbnQKICAgIGZyYW1lX2RpZyAtMgogICAgYjw9CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5MAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCg==", + "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": { @@ -1233,6 +1238,67 @@ "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": {} diff --git a/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc56.json b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc56.json new file mode 100644 index 0000000..e03b9b5 --- /dev/null +++ b/tests/artifacts/primitive-ops/data/PrimitiveOpsContract.arc56.json @@ -0,0 +1,1624 @@ +{ + "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/state-ops/contract.algo.ts b/tests/artifacts/state-ops/contract.algo.ts index 328cd36..ac97863 100644 --- a/tests/artifacts/state-ops/contract.algo.ts +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -17,6 +17,7 @@ import { Uint64, uint64, } from '@algorandfoundation/algorand-typescript' +import { Address, Bool, Byte, DynamicBytes, Str, UintN128, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' function get_1st_ref_index(): uint64 { return op.btoi(Txn.applicationArgs(1)) @@ -48,13 +49,12 @@ export class StateAcctParamsGetContract extends arc4.Contract { } @arc4.abimethod() - public verify_acct_auth_addr(a: Account): Account { + public verify_acct_auth_addr(a: Account): Address { const [value, funded] = op.AcctParams.acctAuthAddr(a) const [value_index, funded_index] = op.AcctParams.acctAuthAddr(get_1st_ref_index()) assert(value === value_index, 'expected value by index to match') assert(funded === funded_index, 'expected funded by index to match') - // TODO: return arc4.Address(value) - return value + return new Address(value) } @arc4.abimethod() @@ -218,53 +218,48 @@ export class StateAssetParamsContract extends arc4.Contract { } @arc4.abimethod() - public verify_asset_params_get_manager(a: Asset): Account { + public verify_asset_params_get_manager(a: Asset): Address { const [value, exists] = op.AssetParams.assetManager(a) const [value_index, exists_index] = op.AssetParams.assetManager(get_1st_ref_index()) assert(value === value_index, 'expected value by index to match') assert(exists === exists_index, 'expected exists by index to match') - // TODO: return arc4.Address(value) - return value + return new Address(value) } @arc4.abimethod() - public verify_asset_params_get_reserve(a: Asset): Account { + public verify_asset_params_get_reserve(a: Asset): Address { const [value, exists] = op.AssetParams.assetReserve(a) const [value_index, exists_index] = op.AssetParams.assetReserve(get_1st_ref_index()) assert(value === value_index, 'expected value by index to match') assert(exists === exists_index, 'expected exists by index to match') - // TODO: return arc4.Address(value) - return value + return new Address(value) } @arc4.abimethod() - public verify_asset_params_get_freeze(a: Asset): Account { + public verify_asset_params_get_freeze(a: Asset): Address { const [value, exists] = op.AssetParams.assetFreeze(a) const [value_index, exists_index] = op.AssetParams.assetFreeze(get_1st_ref_index()) assert(value === value_index, 'expected value by index to match') assert(exists === exists_index, 'expected exists by index to match') - // TODO: return arc4.Address(value) - return value + return new Address(value) } @arc4.abimethod() - public verify_asset_params_get_clawback(a: Asset): Account { + public verify_asset_params_get_clawback(a: Asset): Address { const [value, exists] = op.AssetParams.assetClawback(a) const [value_index, exists_index] = op.AssetParams.assetClawback(get_1st_ref_index()) assert(value === value_index, 'expected value by index to match') assert(exists === exists_index, 'expected exists by index to match') - // TODO: return arc4.Address(value) - return value + return new Address(value) } @arc4.abimethod() - public verify_asset_params_get_creator(a: Asset): Account { + public verify_asset_params_get_creator(a: Asset): Address { const [value, exists] = op.AssetParams.assetCreator(a) const [value_index, exists_index] = op.AssetParams.assetCreator(get_1st_ref_index()) assert(value === value_index, 'expected value by index to match') assert(exists === exists_index, 'expected exists by index to match') - // TODO: return arc4.Address(value) - return value + return new Address(value) } } @@ -333,24 +328,21 @@ export class StateAppParamsContract extends arc4.Contract { } @arc4.abimethod() - public verify_app_params_get_creator(a: Application): Account { + public verify_app_params_get_creator(a: Application): Address { const [value, exists] = op.AppParams.appCreator(a) const [value_index, exists_index] = op.AppParams.appCreator(get_1st_ref_index()) assert(value === value_index, 'expected value by index to match') assert(exists === exists_index, 'expected exists by index to match') - // TODO: return arc4.Address(value) - return value + return new Address(value) } @arc4.abimethod() - public verify_app_params_get_address(a: Application): Account { + public verify_app_params_get_address(a: Application): Address { const [value, exists] = op.AppParams.appAddress(a) const [value_index, exists_index] = op.AppParams.appAddress(get_1st_ref_index()) - // TODO: recompile when puya ts is ready assert(value.bytes.toString() === value_index.bytes.toString(), 'expected value by index to match') assert(exists === exists_index, 'expected exists by index to match') - // TODO: return arc4.Address(value) - return value + return new Address(value) } } @@ -359,9 +351,8 @@ export class StateAppGlobalExContract extends arc4.Contract { globalBytes = GlobalState({ key: Bytes('global_bytes'), initialValue: Bytes('dummy_bytes') }) global_uint64_explicit = GlobalState({ initialValue: Uint64(2) }) global_bytes_explicit = GlobalState({ initialValue: Bytes('dummy_bytes') }) - // TODO: uncomment when arc4 types are ready - // globalArc4Bytes = GlobalState({ key: Bytes('global_arc4_bytes'), initialValue: arc4.DynamicBytes('dummy_arc4_bytes') }) - // global_arc4_bytes_explicit = GlobalState({ initialValue: arc4.DynamicBytes('dummy_arc4_bytes') }) + globalArc4Bytes = GlobalState({ key: Bytes('global_arc4_bytes'), initialValue: new DynamicBytes('dummy_arc4_bytes') }) + global_arc4_bytes_explicit = GlobalState({ initialValue: new DynamicBytes('dummy_arc4_bytes') }) } export class StateAppGlobalContract extends arc4.Contract { @@ -409,16 +400,13 @@ export class StateAppGlobalContract extends arc4.Contract { export class StateAppLocalExContract extends arc4.Contract { localUint64 = LocalState({ key: 'local_uint64' }) localBytes = LocalState({ key: 'local_bytes' }) - - // TODO: uncomment when arc4 types are ready - // localArc4Bytes = LocalState({ key: "local_arc4_bytes" }) + localArc4Bytes = LocalState({ key: 'local_arc4_bytes' }) @arc4.abimethod({ allowActions: ['OptIn'] }) - optIn(): void { + opt_in(): void { this.localBytes(Global.creatorAddress).value = Bytes('dummy_bytes_from_external_contract') this.localUint64(Global.creatorAddress).value = Uint64(99) - // TODO: uncomment when arc4 types are ready - // this.localArc4Bytes(Global.creatorAddress).value = arc4.DynamicBytes("dummy_arc4_bytes") + this.localArc4Bytes(Global.creatorAddress).value = new DynamicBytes('dummy_arc4_bytes') } } @@ -600,5 +588,277 @@ export class ItxnDemoContract extends BaseContract { } } -// TODO: add GlobalStateContract when arc4 types are ready -// TODO: add LocalStateContract when arc4 types are ready +export class GlobalStateContract extends arc4.Contract { + // Implicit key state variables + implicitKeyArc4UintN64 = GlobalState({ initialValue: new UintN64(1337) }) + implicitKeyArc4Str = GlobalState({ initialValue: new Str('Hello') }) + implicitKeyArc4Byte = GlobalState({ initialValue: new Byte(0) }) + implicitKeyArc4Bool = GlobalState({ initialValue: new Bool(true) }) + implicitKeyArc4Address = GlobalState({ initialValue: new Address(Global.creatorAddress) }) + implicitKeyArc4UintN128 = GlobalState({ initialValue: new UintN128(2n ** 100n) }) + implicitKeyArc4DynamicBytes = GlobalState({ initialValue: new DynamicBytes('dynamic bytes') }) + + // Explicit key state variables + arc4UintN64 = GlobalState({ initialValue: new UintN64(1337), key: 'explicit_key_arc4_uintn64' }) + arc4Str = GlobalState({ initialValue: new Str('Hello'), key: 'explicit_key_arc4_str' }) + arc4Byte = GlobalState({ initialValue: new Byte(0), key: 'explicit_key_arc4_byte' }) + arc4Bool = GlobalState({ initialValue: new Bool(true), key: 'explicit_key_arc4_bool' }) + arc4Address = GlobalState({ initialValue: new Address(Global.creatorAddress), key: 'explicit_key_arc4_address' }) + arc4UintN128 = GlobalState({ initialValue: new UintN128(2n ** 100n), key: 'explicit_key_arc4_uintn128' }) + arc4DynamicBytes = GlobalState({ initialValue: new DynamicBytes('dynamic bytes'), key: 'explicit_key_arc4_dynamic_bytes' }) + + // Getter methods for implicit key state variables + @arc4.abimethod() + get_implicit_key_arc4_uintn64(): UintN64 { + return this.implicitKeyArc4UintN64.value + } + + @arc4.abimethod() + get_implicit_key_arc4_str(): Str { + return this.implicitKeyArc4Str.value + } + + @arc4.abimethod() + get_implicit_key_arc4_byte(): Byte { + return this.implicitKeyArc4Byte.value + } + + @arc4.abimethod() + get_implicit_key_arc4_bool(): arc4.Bool { + return this.implicitKeyArc4Bool.value + } + + @arc4.abimethod() + get_implicit_key_arc4_address(): Address { + return this.implicitKeyArc4Address.value + } + + @arc4.abimethod() + get_implicit_key_arc4_uintn128(): UintN128 { + return this.implicitKeyArc4UintN128.value + } + + @arc4.abimethod() + get_implicit_key_arc4_dynamic_bytes(): DynamicBytes { + return this.implicitKeyArc4DynamicBytes.value + } + + // Getter methods for explicit key state variables + @arc4.abimethod() + get_arc4_uintn64(): UintN64 { + return this.arc4UintN64.value + } + + @arc4.abimethod() + get_arc4_str(): Str { + return this.arc4Str.value + } + + @arc4.abimethod() + get_arc4_byte(): Byte { + return this.arc4Byte.value + } + + @arc4.abimethod() + get_arc4_bool(): arc4.Bool { + return this.arc4Bool.value + } + + @arc4.abimethod() + get_arc4_address(): Address { + return this.arc4Address.value + } + + @arc4.abimethod() + get_arc4_uintn128(): UintN128 { + return this.arc4UintN128.value + } + + @arc4.abimethod() + get_arc4_dynamic_bytes(): DynamicBytes { + return this.arc4DynamicBytes.value + } + + // Setter methods for implicit key state variables + @arc4.abimethod() + set_implicit_key_arc4_uintn64(value: UintN64) { + this.implicitKeyArc4UintN64.value = value + } + + @arc4.abimethod() + set_implicit_key_arc4_str(value: Str) { + this.implicitKeyArc4Str.value = value + } + + @arc4.abimethod() + set_implicit_key_arc4_byte(value: Byte) { + this.implicitKeyArc4Byte.value = value + } + + @arc4.abimethod() + set_implicit_key_arc4_bool(value: Bool) { + this.implicitKeyArc4Bool.value = value + } + + @arc4.abimethod() + set_implicit_key_arc4_address(value: Address) { + this.implicitKeyArc4Address.value = value + } + + @arc4.abimethod() + set_implicit_key_arc4_uintn128(value: UintN128) { + this.implicitKeyArc4UintN128.value = value + } + + @arc4.abimethod() + set_implicit_key_arc4_dynamic_bytes(value: DynamicBytes) { + this.implicitKeyArc4DynamicBytes.value = value + } + + // Setter methods for explicit key state variables + @arc4.abimethod() + set_arc4_uintn64(value: UintN64) { + this.arc4UintN64.value = value + } + + @arc4.abimethod() + set_arc4_str(value: Str) { + this.arc4Str.value = value + } + + @arc4.abimethod() + set_arc4_byte(value: Byte) { + this.arc4Byte.value = value + } + + @arc4.abimethod() + set_arc4_bool(value: Bool) { + this.arc4Bool.value = value + } + + @arc4.abimethod() + set_arc4_address(value: Address) { + this.arc4Address.value = value + } + + @arc4.abimethod() + set_arc4_uintn128(value: UintN128) { + this.arc4UintN128.value = value + } + + @arc4.abimethod() + set_arc4_dynamic_bytes(value: DynamicBytes) { + this.arc4DynamicBytes.value = value + } +} + +export class LocalStateContract extends arc4.Contract { + // Implicit key state variables + implicitKeyArc4UintN64 = LocalState() + implicitKeyArc4Str = LocalState() + implicitKeyArc4Byte = LocalState() + implicitKeyArc4Bool = LocalState() + implicitKeyArc4Address = LocalState
() + implicitKeyArc4UintN128 = LocalState() + implicitKeyArc4DynamicBytes = LocalState() + + // Explicit key state variables + arc4UintN64 = LocalState({ key: 'explicit_key_arc4_uintn64' }) + arc4Str = LocalState({ key: 'explicit_key_arc4_str' }) + arc4Byte = LocalState({ key: 'explicit_key_arc4_byte' }) + arc4Bool = LocalState({ key: 'explicit_key_arc4_bool' }) + arc4Address = LocalState
({ key: 'explicit_key_arc4_address' }) + arc4UintN128 = LocalState({ key: 'explicit_key_arc4_uintn128' }) + arc4DynamicBytes = LocalState({ key: 'explicit_key_arc4_dynamic_bytes' }) + + @arc4.abimethod({ allowActions: ['OptIn'] }) + opt_in(): void { + this.implicitKeyArc4UintN64(Global.creatorAddress).value = new UintN64(1337) + this.implicitKeyArc4Str(Global.creatorAddress).value = new Str('Hello') + this.implicitKeyArc4Byte(Global.creatorAddress).value = new Byte(0) + this.implicitKeyArc4Bool(Global.creatorAddress).value = new Bool(true) + this.implicitKeyArc4Address(Global.creatorAddress).value = new Address(Global.creatorAddress) + this.implicitKeyArc4UintN128(Global.creatorAddress).value = new UintN128(2n ** 100n) + this.implicitKeyArc4DynamicBytes(Global.creatorAddress).value = new DynamicBytes('dynamic bytes') + + this.arc4UintN64(Global.creatorAddress).value = new UintN64(1337) + this.arc4Str(Global.creatorAddress).value = new Str('Hello') + this.arc4Byte(Global.creatorAddress).value = new Byte(0) + this.arc4Bool(Global.creatorAddress).value = new Bool(true) + this.arc4Address(Global.creatorAddress).value = new Address(Global.creatorAddress) + this.arc4UintN128(Global.creatorAddress).value = new UintN128(2n ** 100n) + this.arc4DynamicBytes(Global.creatorAddress).value = new DynamicBytes('dynamic bytes') + } + + // Getter methods for implicit key state variables + @arc4.abimethod() + get_implicit_key_arc4_uintn64(a: Account): UintN64 { + return this.implicitKeyArc4UintN64(a).value + } + + @arc4.abimethod() + get_implicit_key_arc4_str(a: Account): Str { + return this.implicitKeyArc4Str(a).value + } + + @arc4.abimethod() + get_implicit_key_arc4_byte(a: Account): Byte { + return this.implicitKeyArc4Byte(a).value + } + + @arc4.abimethod() + get_implicit_key_arc4_bool(a: Account): Bool { + return this.implicitKeyArc4Bool(a).value + } + + @arc4.abimethod() + get_implicit_key_arc4_address(a: Account): Address { + return this.implicitKeyArc4Address(a).value + } + + @arc4.abimethod() + get_implicit_key_arc4_uintn128(a: Account): UintN128 { + return this.implicitKeyArc4UintN128(a).value + } + + @arc4.abimethod() + get_implicit_key_arc4_dynamic_bytes(a: Account): DynamicBytes { + return this.implicitKeyArc4DynamicBytes(a).value + } + + // Getter methods for explicit key state variables + @arc4.abimethod() + get_arc4_uintn64(a: Account): arc4.UintN64 { + return this.arc4UintN64(a).value + } + + @arc4.abimethod() + get_arc4_str(a: Account): Str { + return this.arc4Str(a).value + } + + @arc4.abimethod() + get_arc4_byte(a: Account): Byte { + return this.arc4Byte(a).value + } + + @arc4.abimethod() + get_arc4_bool(a: Account): Bool { + return this.arc4Bool(a).value + } + + @arc4.abimethod() + get_arc4_address(a: Account): Address { + return this.arc4Address(a).value + } + + @arc4.abimethod() + get_arc4_uintn128(a: Account): UintN128 { + return this.arc4UintN128(a).value + } + + @arc4.abimethod() + get_arc4_dynamic_bytes(a: Account): DynamicBytes { + return this.arc4DynamicBytes(a).value + } +} diff --git a/tests/artifacts/state-ops/data/GlobalStateContract.approval.teal b/tests/artifacts/state-ops/data/GlobalStateContract.approval.teal new file mode 100644 index 0000000..caeee01 --- /dev/null +++ b/tests/artifacts/state-ops/data/GlobalStateContract.approval.teal @@ -0,0 +1,1073 @@ +#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 new file mode 100644 index 0000000..84d439a --- /dev/null +++ b/tests/artifacts/state-ops/data/GlobalStateContract.arc32.json @@ -0,0 +1,528 @@ +{ + "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 new file mode 100644 index 0000000..261d8c7 --- /dev/null +++ b/tests/artifacts/state-ops/data/GlobalStateContract.arc56.json @@ -0,0 +1,736 @@ +{ + "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 new file mode 100644 index 0000000..cccf7dc --- /dev/null +++ b/tests/artifacts/state-ops/data/GlobalStateContract.clear.teal @@ -0,0 +1,5 @@ +#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 new file mode 100644 index 0000000..52978e5 --- /dev/null +++ b/tests/artifacts/state-ops/data/ITxnOpsContract.approval.teal @@ -0,0 +1,134 @@ +#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 new file mode 100644 index 0000000..7d19134 --- /dev/null +++ b/tests/artifacts/state-ops/data/ITxnOpsContract.arc32.json @@ -0,0 +1,50 @@ +{ + "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 new file mode 100644 index 0000000..185eb45 --- /dev/null +++ b/tests/artifacts/state-ops/data/ITxnOpsContract.arc56.json @@ -0,0 +1,90 @@ +{ + "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 new file mode 100644 index 0000000..b00b7bf --- /dev/null +++ b/tests/artifacts/state-ops/data/ITxnOpsContract.clear.teal @@ -0,0 +1,5 @@ +#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 new file mode 100644 index 0000000..a844d3a --- /dev/null +++ b/tests/artifacts/state-ops/data/ItxnDemoContract.approval.teal @@ -0,0 +1,485 @@ +#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 new file mode 100644 index 0000000..d7fd8f9 --- /dev/null +++ b/tests/artifacts/state-ops/data/ItxnDemoContract.clear.teal @@ -0,0 +1,5 @@ +#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 new file mode 100644 index 0000000..625363e --- /dev/null +++ b/tests/artifacts/state-ops/data/LocalStateContract.approval.teal @@ -0,0 +1,802 @@ +#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 new file mode 100644 index 0000000..5bc511d --- /dev/null +++ b/tests/artifacts/state-ops/data/LocalStateContract.arc32.json @@ -0,0 +1,359 @@ +{ + "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 new file mode 100644 index 0000000..f2de7ea --- /dev/null +++ b/tests/artifacts/state-ops/data/LocalStateContract.arc56.json @@ -0,0 +1,507 @@ +{ + "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 new file mode 100644 index 0000000..277d4be --- /dev/null +++ b/tests/artifacts/state-ops/data/LocalStateContract.clear.teal @@ -0,0 +1,5 @@ +#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 index 0b5e66e..dceec00 100644 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal @@ -1,770 +1,730 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAcctParamsGetContract.approval_program: - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): +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 main_bare_routing@16 - 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" + 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 main_verify_acct_balance_route@2 main_verify_acct_min_balance_route@3 main_verify_acct_auth_addr_route@4 main_verify_acct_total_num_uint_route@5 main_verify_acct_total_num_byte_slice_route@6 main_verify_acct_total_extra_app_pages_route@7 main_verify_acct_total_apps_created_route@8 main_verify_acct_total_apps_opted_in_route@9 main_verify_acct_total_assets_created_route@10 main_verify_acct_total_assets_route@11 main_verify_acct_total_boxes_route@12 main_verify_acct_total_box_bytes_route@13 - err // reject transaction + 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 -main_verify_acct_balance_route@2: - // tests/artifacts/StateOps/contract.py:25 +__puya_arc4_router___verify_acct_balance_route@2: + // tests/artifacts/state-ops/contract.algo.ts:27 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:25 + // tests/artifacts/state-ops/contract.algo.ts:27 // @arc4.abimethod() callsub verify_acct_balance itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_min_balance_route@3: - // tests/artifacts/StateOps/contract.py:38 +__puya_arc4_router___verify_acct_min_balance_route@3: + // tests/artifacts/state-ops/contract.algo.ts:39 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:38 + // tests/artifacts/state-ops/contract.algo.ts:39 // @arc4.abimethod() callsub verify_acct_min_balance itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_auth_addr_route@4: - // tests/artifacts/StateOps/contract.py:51 +__puya_arc4_router___verify_acct_auth_addr_route@4: + // tests/artifacts/state-ops/contract.algo.ts:51 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:51 + // tests/artifacts/state-ops/contract.algo.ts:51 // @arc4.abimethod() callsub verify_acct_auth_addr - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_total_num_uint_route@5: - // tests/artifacts/StateOps/contract.py:59 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:59 + // tests/artifacts/state-ops/contract.algo.ts:60 // @arc4.abimethod() callsub verify_acct_total_num_uint itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_total_num_byte_slice_route@6: - // tests/artifacts/StateOps/contract.py:67 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:67 + // tests/artifacts/state-ops/contract.algo.ts:69 // @arc4.abimethod() callsub verify_acct_total_num_byte_slice itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_total_extra_app_pages_route@7: - // tests/artifacts/StateOps/contract.py:77 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:77 + // tests/artifacts/state-ops/contract.algo.ts:78 // @arc4.abimethod() callsub verify_acct_total_extra_app_pages itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_total_apps_created_route@8: - // tests/artifacts/StateOps/contract.py:87 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:87 + // tests/artifacts/state-ops/contract.algo.ts:87 // @arc4.abimethod() callsub verify_acct_total_apps_created itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_total_apps_opted_in_route@9: - // tests/artifacts/StateOps/contract.py:95 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:95 + // tests/artifacts/state-ops/contract.algo.ts:96 // @arc4.abimethod() callsub verify_acct_total_apps_opted_in itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_total_assets_created_route@10: - // tests/artifacts/StateOps/contract.py:103 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:103 + // tests/artifacts/state-ops/contract.algo.ts:105 // @arc4.abimethod() callsub verify_acct_total_assets_created itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_total_assets_route@11: - // tests/artifacts/StateOps/contract.py:113 +__puya_arc4_router___verify_acct_total_assets_route@11: + // tests/artifacts/state-ops/contract.algo.ts:114 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:113 + // tests/artifacts/state-ops/contract.algo.ts:114 // @arc4.abimethod() callsub verify_acct_total_assets itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_total_boxes_route@12: - // tests/artifacts/StateOps/contract.py:121 +__puya_arc4_router___verify_acct_total_boxes_route@12: + // tests/artifacts/state-ops/contract.algo.ts:123 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:121 + // tests/artifacts/state-ops/contract.algo.ts:123 // @arc4.abimethod() callsub verify_acct_total_boxes itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_acct_total_box_bytes_route@13: - // tests/artifacts/StateOps/contract.py:129 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): + 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/StateOps/contract.py:129 + // tests/artifacts/state-ops/contract.algo.ts:132 // @arc4.abimethod() callsub verify_acct_total_box_bytes itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_bare_routing@16: - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): +__puya_arc4_router___bare_routing@16: + // tests/artifacts/state-ops/contract.algo.ts:26 + // export class StateAcctParamsGetContract extends arc4.Contract { txn OnCompletion - ! - assert // reject transaction + bnz __puya_arc4_router___after_if_else@20 txn ApplicationID ! - assert // is creating - int 1 - return + 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.StateOps.contract.StateAcctParamsGetContract.verify_acct_balance(a: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_balance(a: bytes) -> uint64: verify_acct_balance: - // tests/artifacts/StateOps/contract.py:25-26 + // tests/artifacts/state-ops/contract.algo.ts:27-28 // @arc4.abimethod() - // def verify_acct_balance(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_balance(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:27 - // value, funded = op.AcctParamsGet.acct_balance(a) + // tests/artifacts/state-ops/contract.algo.ts:29 + // const [value, funded] = op.AcctParams.acctBalance(a) frame_dig -1 acct_params_get AcctBalance - swap - // tests/artifacts/StateOps/contract.py:28 - // value_index, funded_index = op.AcctParamsGet.acct_balance(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:29 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:30 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:31 - // assert value == a.balance, "expected Account balance 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/StateOps/contract.py:32 - // assert value == algopy.op.balance(a), "expected op.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/StateOps/contract.py:34 - // _get_1st_ref_index() - callsub _get_1st_ref_index - // tests/artifacts/StateOps/contract.py:33-35 - // assert value == algopy.op.balance( - // _get_1st_ref_index() - // ), "expected op.balance by index 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/StateOps/contract.py:36 + // tests/artifacts/state-ops/contract.algo.ts:36 // return value retsub -// tests.artifacts.StateOps.contract._get_1st_ref_index() -> uint64: -_get_1st_ref_index: - // tests/artifacts/StateOps/contract.py:19-20 - // @subroutine - // def _get_1st_ref_index() -> UInt64: +// 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/StateOps/contract.py:21 - // return op.btoi(Txn.application_args(1)) - txna ApplicationArgs 1 + // tests/artifacts/state-ops/contract.algo.ts:23 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs btoi retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_min_balance(a: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_min_balance(a: bytes) -> uint64: verify_acct_min_balance: - // tests/artifacts/StateOps/contract.py:38-39 + // tests/artifacts/state-ops/contract.algo.ts:39-40 // @arc4.abimethod() - // def verify_acct_min_balance(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_min_balance(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:40 - // value, funded = op.AcctParamsGet.acct_min_balance(a) + // tests/artifacts/state-ops/contract.algo.ts:41 + // const [value, funded] = op.AcctParams.acctMinBalance(a) frame_dig -1 acct_params_get AcctMinBalance - swap - // tests/artifacts/StateOps/contract.py:41 - // value_index, funded_index = op.AcctParamsGet.acct_min_balance(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:42 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:43 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:44 - // assert value == a.min_balance, "expected Account min_balance 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/StateOps/contract.py:45 - // assert value == algopy.op.min_balance(a), "expected op.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/StateOps/contract.py:47 - // _get_1st_ref_index() - callsub _get_1st_ref_index - // tests/artifacts/StateOps/contract.py:46-48 - // assert value == algopy.op.min_balance( - // _get_1st_ref_index() - // ), "expected op.min_balance by index 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/StateOps/contract.py:49 + // tests/artifacts/state-ops/contract.algo.ts:48 // return value retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_auth_addr(a: bytes) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_auth_addr(a: bytes) -> bytes: verify_acct_auth_addr: - // tests/artifacts/StateOps/contract.py:51-52 + // tests/artifacts/state-ops/contract.algo.ts:51-52 // @arc4.abimethod() - // def verify_acct_auth_addr(self, a: algopy.Account) -> arc4.Address: + // public verify_acct_auth_addr(a: Account): Address { proto 1 1 - // tests/artifacts/StateOps/contract.py:53 - // value, funded = op.AcctParamsGet.acct_auth_addr(a) + // tests/artifacts/state-ops/contract.algo.ts:53 + // const [value, funded] = op.AcctParams.acctAuthAddr(a) frame_dig -1 acct_params_get AcctAuthAddr - swap - // tests/artifacts/StateOps/contract.py:54 - // value_index, funded_index = op.AcctParamsGet.acct_auth_addr(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:55 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:56 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:57 - // return arc4.Address(value) + // tests/artifacts/state-ops/contract.algo.ts:57 + // return new Address(value) retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_num_uint(a: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_num_uint(a: bytes) -> uint64: verify_acct_total_num_uint: - // tests/artifacts/StateOps/contract.py:59-60 + // tests/artifacts/state-ops/contract.algo.ts:60-61 // @arc4.abimethod() - // def verify_acct_total_num_uint(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_total_num_uint(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:61 - // value, funded = op.AcctParamsGet.acct_total_num_uint(a) + // tests/artifacts/state-ops/contract.algo.ts:62 + // const [value, funded] = op.AcctParams.acctTotalNumUint(a) frame_dig -1 acct_params_get AcctTotalNumUint - swap - // tests/artifacts/StateOps/contract.py:62 - // value_index, funded_index = op.AcctParamsGet.acct_total_num_uint(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:63 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:64 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:65 + // tests/artifacts/state-ops/contract.algo.ts:66 // return value retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_num_byte_slice(a: bytes) -> uint64: +// 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/StateOps/contract.py:67-68 + // tests/artifacts/state-ops/contract.algo.ts:69-70 // @arc4.abimethod() - // def verify_acct_total_num_byte_slice(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_total_num_byte_slice(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:69 - // value, funded = op.AcctParamsGet.acct_total_num_byte_slice(a) + // tests/artifacts/state-ops/contract.algo.ts:71 + // const [value, funded] = op.AcctParams.acctTotalNumByteSlice(a) frame_dig -1 acct_params_get AcctTotalNumByteSlice - swap - // tests/artifacts/StateOps/contract.py:71 - // _get_1st_ref_index() - callsub _get_1st_ref_index - // tests/artifacts/StateOps/contract.py:70-72 - // value_index, funded_index = op.AcctParamsGet.acct_total_num_byte_slice( - // _get_1st_ref_index() - // ) + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:73 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:74 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:75 + // tests/artifacts/state-ops/contract.algo.ts:75 // return value retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_extra_app_pages(a: bytes) -> uint64: +// 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/StateOps/contract.py:77-78 + // tests/artifacts/state-ops/contract.algo.ts:78-79 // @arc4.abimethod() - // def verify_acct_total_extra_app_pages(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_total_extra_app_pages(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:79 - // value, funded = op.AcctParamsGet.acct_total_extra_app_pages(a) + // tests/artifacts/state-ops/contract.algo.ts:80 + // const [value, funded] = op.AcctParams.acctTotalExtraAppPages(a) frame_dig -1 acct_params_get AcctTotalExtraAppPages - swap - // tests/artifacts/StateOps/contract.py:81 - // _get_1st_ref_index() - callsub _get_1st_ref_index - // tests/artifacts/StateOps/contract.py:80-82 - // value_index, funded_index = op.AcctParamsGet.acct_total_extra_app_pages( - // _get_1st_ref_index() - // ) + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:83 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:84 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:85 + // tests/artifacts/state-ops/contract.algo.ts:84 // return value retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_apps_created(a: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_apps_created(a: bytes) -> uint64: verify_acct_total_apps_created: - // tests/artifacts/StateOps/contract.py:87-88 + // tests/artifacts/state-ops/contract.algo.ts:87-88 // @arc4.abimethod() - // def verify_acct_total_apps_created(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_total_apps_created(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:89 - // value, funded = op.AcctParamsGet.acct_total_apps_created(a) + // tests/artifacts/state-ops/contract.algo.ts:89 + // const [value, funded] = op.AcctParams.acctTotalAppsCreated(a) frame_dig -1 acct_params_get AcctTotalAppsCreated - swap - // tests/artifacts/StateOps/contract.py:90 - // value_index, funded_index = op.AcctParamsGet.acct_total_apps_created(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:91 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:92 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:93 + // tests/artifacts/state-ops/contract.algo.ts:93 // return value retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_apps_opted_in(a: bytes) -> uint64: +// 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/StateOps/contract.py:95-96 + // tests/artifacts/state-ops/contract.algo.ts:96-97 // @arc4.abimethod() - // def verify_acct_total_apps_opted_in(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_total_apps_opted_in(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:97 - // value, funded = op.AcctParamsGet.acct_total_apps_opted_in(a) + // tests/artifacts/state-ops/contract.algo.ts:98 + // const [value, funded] = op.AcctParams.acctTotalAppsOptedIn(a) frame_dig -1 acct_params_get AcctTotalAppsOptedIn - swap - // tests/artifacts/StateOps/contract.py:98 - // value_index, funded_index = op.AcctParamsGet.acct_total_apps_opted_in(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:99 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:100 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:101 + // tests/artifacts/state-ops/contract.algo.ts:102 // return value retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_assets_created(a: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_assets_created(a: bytes) -> uint64: verify_acct_total_assets_created: - // tests/artifacts/StateOps/contract.py:103-104 + // tests/artifacts/state-ops/contract.algo.ts:105-106 // @arc4.abimethod() - // def verify_acct_total_assets_created(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_total_assets_created(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:105 - // value, funded = op.AcctParamsGet.acct_total_assets_created(a) + // tests/artifacts/state-ops/contract.algo.ts:107 + // const [value, funded] = op.AcctParams.acctTotalAssetsCreated(a) frame_dig -1 acct_params_get AcctTotalAssetsCreated - swap - // tests/artifacts/StateOps/contract.py:107 - // _get_1st_ref_index() - callsub _get_1st_ref_index - // tests/artifacts/StateOps/contract.py:106-108 - // value_index, funded_index = op.AcctParamsGet.acct_total_assets_created( - // _get_1st_ref_index() - // ) + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:109 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:110 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:111 + // tests/artifacts/state-ops/contract.algo.ts:111 // return value retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_assets(a: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_assets(a: bytes) -> uint64: verify_acct_total_assets: - // tests/artifacts/StateOps/contract.py:113-114 + // tests/artifacts/state-ops/contract.algo.ts:114-115 // @arc4.abimethod() - // def verify_acct_total_assets(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_total_assets(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:115 - // value, funded = op.AcctParamsGet.acct_total_assets(a) + // tests/artifacts/state-ops/contract.algo.ts:116 + // const [value, funded] = op.AcctParams.acctTotalAssets(a) frame_dig -1 acct_params_get AcctTotalAssets - swap - // tests/artifacts/StateOps/contract.py:116 - // value_index, funded_index = op.AcctParamsGet.acct_total_assets(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:117 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:118 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:119 + // tests/artifacts/state-ops/contract.algo.ts:120 // return value retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_boxes(a: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_boxes(a: bytes) -> uint64: verify_acct_total_boxes: - // tests/artifacts/StateOps/contract.py:121-122 + // tests/artifacts/state-ops/contract.algo.ts:123-124 // @arc4.abimethod() - // def verify_acct_total_boxes(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_total_boxes(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:123 - // value, funded = op.AcctParamsGet.acct_total_boxes(a) + // tests/artifacts/state-ops/contract.algo.ts:125 + // const [value, funded] = op.AcctParams.acctTotalBoxes(a) frame_dig -1 acct_params_get AcctTotalBoxes - swap - // tests/artifacts/StateOps/contract.py:124 - // value_index, funded_index = op.AcctParamsGet.acct_total_boxes(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:125 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:126 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:127 + // tests/artifacts/state-ops/contract.algo.ts:129 // return value retsub -// tests.artifacts.StateOps.contract.StateAcctParamsGetContract.verify_acct_total_box_bytes(a: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_box_bytes(a: bytes) -> uint64: verify_acct_total_box_bytes: - // tests/artifacts/StateOps/contract.py:129-130 + // tests/artifacts/state-ops/contract.algo.ts:132-133 // @arc4.abimethod() - // def verify_acct_total_box_bytes(self, a: algopy.Account) -> algopy.UInt64: + // public verify_acct_total_box_bytes(a: Account): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:131 - // value, funded = op.AcctParamsGet.acct_total_box_bytes(a) + // tests/artifacts/state-ops/contract.algo.ts:134 + // const [value, funded] = op.AcctParams.acctTotalBoxBytes(a) frame_dig -1 acct_params_get AcctTotalBoxBytes - swap - // tests/artifacts/StateOps/contract.py:132 - // value_index, funded_index = op.AcctParamsGet.acct_total_box_bytes(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:133 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:134 - // assert funded == funded_index, "expected funded by index to match" - cover 2 + // 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/StateOps/contract.py:135 + // 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 index 16b66ef..4fbd3f2 100644 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json @@ -62,8 +62,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxNgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF9iYWxhbmNlKGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZShhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfYXV0aF9hZGRyKGFjY291bnQpYWRkcmVzcyIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlKGFjY291bnQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cyhhY2NvdW50KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYWNjb3VudCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlcyhhY2NvdW50KXVpbnQ2NCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2FjY3RfYmFsYW5jZV9yb3V0ZUAyIG1haW5fdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Vfcm91dGVAMyBtYWluX3ZlcmlmeV9hY2N0X2F1dGhfYWRkcl9yb3V0ZUA0IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnRfcm91dGVANSBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDYgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXNfcm91dGVANyBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZF9yb3V0ZUA4IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbl9yb3V0ZUA5IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWRfcm91dGVAMTAgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfcm91dGVAMTEgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMiBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlc19yb3V0ZUAxMwogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9iYWxhbmNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X21pbl9iYWxhbmNlX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZQogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF9hdXRoX2FkZHJfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2F1dGhfYWRkcgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlc19yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZF9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW5fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4KICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjExMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2JveGVzX3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcwogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXNfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlcwogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQKICAgIC8vIGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfYmFsYW5jZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNS0yNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF9iYWxhbmNlKHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhbGdvcHkuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjcKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfYmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOAogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF9iYWxhbmNlKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzAKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMQogICAgLy8gYXNzZXJ0IHZhbHVlID09IGEuYmFsYW5jZSwgImV4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaCIKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMyCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gYWxnb3B5Lm9wLmJhbGFuY2UoYSksICJleHBlY3RlZCBvcC5iYWxhbmNlIHRvIG1hdGNoIgogICAgZnJhbWVfZGlnIC0xCiAgICBiYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5iYWxhbmNlIHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQKICAgIC8vIF9nZXRfMXN0X3JlZl9pbmRleCgpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMzLTM1CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gYWxnb3B5Lm9wLmJhbGFuY2UoCiAgICAvLyAgICAgX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIC8vICksICJleHBlY3RlZCBvcC5iYWxhbmNlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AuYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5fZ2V0XzFzdF9yZWZfaW5kZXgoKSAtPiB1aW50NjQ6Cl9nZXRfMXN0X3JlZl9pbmRleDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOS0yMAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBfZ2V0XzFzdF9yZWZfaW5kZXgoKSAtPiBVSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMQogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uX2FyZ3MoMSkpCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgtMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Uoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MAogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF9taW5fYmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MQogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF9taW5fYmFsYW5jZShfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MgogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQzCiAgICAvLyBhc3NlcnQgZnVuZGVkID09IGZ1bmRlZF9pbmRleCwgImV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSBhLm1pbl9iYWxhbmNlLCAiZXhwZWN0ZWQgQWNjb3VudCBtaW5fYmFsYW5jZSB0byBtYXRjaCIKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIEFjY291bnQgbWluX2JhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NQogICAgLy8gYXNzZXJ0IHZhbHVlID09IGFsZ29weS5vcC5taW5fYmFsYW5jZShhKSwgImV4cGVjdGVkIG9wLm1pbl9iYWxhbmNlIHRvIG1hdGNoIgogICAgZnJhbWVfZGlnIC0xCiAgICBtaW5fYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AubWluX2JhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NwogICAgLy8gX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYtNDgKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSBhbGdvcHkub3AubWluX2JhbGFuY2UoCiAgICAvLyAgICAgX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIC8vICksICJleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCIKICAgIG1pbl9iYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYWNjdF9hdXRoX2FkZHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTEtNTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfYXV0aF9hZGRyKHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhcmM0LkFkZHJlc3M6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1MwogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF9hdXRoX2FkZHIoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RBdXRoQWRkcgogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU0CiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X2F1dGhfYWRkcihfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEF1dGhBZGRyCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NTUKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo1NgogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU3CiAgICAvLyByZXR1cm4gYXJjNC5BZGRyZXNzKHZhbHVlKQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjU5LTYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KHNlbGYsIGE6IGFsZ29weS5BY2NvdW50KSAtPiBhbGdvcHkuVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjEKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfbnVtX3VpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2MgogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9udW1fdWludChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtVWludAogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjYzCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjQKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2NQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NjctNjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Uoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo2OQogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzEKICAgIC8vIF9nZXRfMXN0X3JlZl9pbmRleCgpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjcwLTcyCiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlKAogICAgLy8gICAgIF9nZXRfMXN0X3JlZl9pbmRleCgpCiAgICAvLyApCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NzMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo3NAogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcyhzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsRXh0cmFBcHBQYWdlcwogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjgxCiAgICAvLyBfZ2V0XzFzdF9yZWZfaW5kZXgoKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4MC04MgogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoCiAgICAvLyAgICAgX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIC8vICkKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxFeHRyYUFwcFBhZ2VzCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6ODMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo4NAogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg3LTg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojg5CiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc0NyZWF0ZWQKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MAogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFwcHNDcmVhdGVkCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTEKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5MgogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjkzCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTUtOTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5Ojk3CiAgICAvLyB2YWx1ZSwgZnVuZGVkID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFwcHNPcHRlZEluCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6OTgKICAgIC8vIHZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXggPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYXBwc19vcHRlZF9pbihfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc09wdGVkSW4KICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo5OQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwMAogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwMQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTAzLTEwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwNQogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzQ3JlYXRlZAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEwNwogICAgLy8gX2dldF8xc3RfcmVmX2luZGV4KCkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTA2LTEwOAogICAgLy8gdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZCgKICAgIC8vICAgICBfZ2V0XzFzdF9yZWZfaW5kZXgoKQogICAgLy8gKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMDkKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTAKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cyhhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTEzLTExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTUKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYXNzZXRzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHMKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTYKICAgIC8vIHZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXggPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYXNzZXRzKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHMKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTcKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTgKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMTkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyMS0xMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoc2VsZiwgYTogYWxnb3B5LkFjY291bnQpIC0+IGFsZ29weS5VSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjMKICAgIC8vIHZhbHVlLCBmdW5kZWQgPSBvcC5BY2N0UGFyYW1zR2V0LmFjY3RfdG90YWxfYm94ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveGVzCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTI0CiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2JveGVzKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hlcwogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyNQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyNgogICAgLy8gYXNzZXJ0IGZ1bmRlZCA9PSBmdW5kZWRfaW5kZXgsICJleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEyNwogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMjktMTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlcyhzZWxmLCBhOiBhbGdvcHkuQWNjb3VudCkgLT4gYWxnb3B5LlVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzMQogICAgLy8gdmFsdWUsIGZ1bmRlZCA9IG9wLkFjY3RQYXJhbXNHZXQuYWNjdF90b3RhbF9ib3hfYnl0ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTMyCiAgICAvLyB2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4ID0gb3AuQWNjdFBhcmFtc0dldC5hY2N0X3RvdGFsX2JveF9ieXRlcyhfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQm94Qnl0ZXMKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzQKICAgIC8vIGFzc2VydCBmdW5kZWQgPT0gZnVuZGVkX2luZGV4LCAiZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzUKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNAogICAgLy8gY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE2CiAgICBwdXNoYnl0ZXNzIDB4NWY1YjQzZTQgMHg3M2RjOTNjNyAweDU2MjZkZmViIDB4ZGM4YTI1YmYgMHgxOThlYmQ4YyAweDIzMDFhYjI2IDB4OWY2OGZjYTYgMHhhOTc1YzJkMSAweGQxZTA0ODAxIDB4YjY5NjZiZTUgMHgxOTVkNTQxOCAweDZhZGFlM2YxIC8vIG1ldGhvZCAidmVyaWZ5X2FjY3RfYmFsYW5jZShhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X2F1dGhfYWRkcihhY2NvdW50KWFkZHJlc3MiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4oYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYWNjb3VudCl1aW50NjQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Vfcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF9hdXRoX2FkZHJfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzX3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbl9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXNfcm91dGVAMTMKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X2JhbGFuY2Vfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2JhbGFuY2UKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X21pbl9iYWxhbmNlX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfYXV0aF9hZGRyX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50X3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXNfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW5fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4KICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2JveGVzX3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfYmFsYW5jZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9iYWxhbmNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3LTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0QmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0QmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEuYmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBBY2NvdW50IGJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBvcC5iYWxhbmNlKGEpLCAnZXhwZWN0ZWQgb3AuYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhbGFuY2UKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIG9wLmJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBvcC5iYWxhbmNlKGdldF8xc3RfcmVmX2luZGV4KCkpLCAnZXhwZWN0ZWQgb3AuYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBiYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5iYWxhbmNlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzktNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MgogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEubWluQmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgbWluX2JhbGFuY2UgdG8gbWF0Y2gnKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgQWNjb3VudCBtaW5fYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoYSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIG1pbl9iYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5taW5fYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBtaW5fYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AubWluX2JhbGFuY2UgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0OAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X2F1dGhfYWRkcihhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9hY2N0X2F1dGhfYWRkcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1MS01MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYTogQWNjb3VudCk6IEFkZHJlc3MgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdEF1dGhBZGRyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0QXV0aEFkZHIoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTcKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAtNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MgogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxOdW1VaW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxOdW1VaW50CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtVWludChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtQnl0ZVNsaWNlKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OC03OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MAogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxFeHRyYUFwcFBhZ2VzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxFeHRyYUFwcFBhZ2VzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODEKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsRXh0cmFBcHBQYWdlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEV4dHJhQXBwUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MgogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg3LTg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzQ3JlYXRlZAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5MQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5MgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTYtOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzT3B0ZWRJbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk5CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc09wdGVkSW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDAKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDIKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUtMTA2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDgKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQXNzZXRzQ3JlYXRlZChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEwCiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNC0xMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE2CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0cyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0cyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExOAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTkKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMy0xMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQm94ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveGVzKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQm94ZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjcKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI4CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMi0xMzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM0CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveEJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hCeXRlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxCb3hCeXRlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM2CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1Ygo=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" }, "state": { "global": { diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json new file mode 100644 index 0000000..0ad82cf --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json @@ -0,0 +1,425 @@ +{ + "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 index d07d34f..c48a376 100644 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAcctParamsGetContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:24 - // class StateAcctParamsGetContract(ARC4Contract): - int 1 +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 index 8dfab14..b48af98 100644 --- a/tests/artifacts/state-ops/data/StateAppGlobalContract.approval.teal +++ b/tests/artifacts/state-ops/data/StateAppGlobalContract.approval.teal @@ -1,34 +1,38 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAppGlobalContract.approval_program: - // tests/artifacts/StateOps/contract.py:422 - // class StateAppGlobalContract(ARC4Contract): +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 main_bare_routing@11 - 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_delete(byte[])void" - method "verify_put_uint64(byte[],uint64)void" - method "verify_put_bytes(byte[],byte[])void" + 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 main_verify_get_bytes_route@2 main_verify_get_uint64_route@3 main_verify_get_ex_bytes_route@4 main_verify_get_ex_uint64_route@5 main_verify_delete_route@6 main_verify_put_uint64_route@7 main_verify_put_bytes_route@8 - err // reject transaction + 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 -main_verify_get_bytes_route@2: - // tests/artifacts/StateOps/contract.py:434 +__puya_arc4_router___verify_get_bytes_route@2: + // tests/artifacts/state-ops/contract.algo.ts:362 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:422 - // class StateAppGlobalContract(ARC4Contract): + 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/StateOps/contract.py:434 + // tests/artifacts/state-ops/contract.algo.ts:362 // @arc4.abimethod() callsub verify_get_bytes dup @@ -37,258 +41,249 @@ main_verify_get_bytes_route@2: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_get_uint64_route@3: - // tests/artifacts/StateOps/contract.py:439 +__puya_arc4_router___verify_get_uint64_route@3: + // tests/artifacts/state-ops/contract.algo.ts:368 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:422 - // class StateAppGlobalContract(ARC4Contract): + 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/StateOps/contract.py:439 + // tests/artifacts/state-ops/contract.algo.ts:368 // @arc4.abimethod() callsub verify_get_uint64 itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_get_ex_bytes_route@4: - // tests/artifacts/StateOps/contract.py:444 +__puya_arc4_router___verify_get_ex_bytes_route@4: + // tests/artifacts/state-ops/contract.algo.ts:374 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:422 - // class StateAppGlobalContract(ARC4Contract): + 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/StateOps/contract.py:444 + // tests/artifacts/state-ops/contract.algo.ts:374 // @arc4.abimethod() callsub verify_get_ex_bytes - swap - dup + dig 1 len itob extract 6 2 - swap + uncover 2 concat - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 3 setbit - byte 0x0003 + pushbytes 0x0003 swap concat swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_get_ex_uint64_route@5: - // tests/artifacts/StateOps/contract.py:448 +__puya_arc4_router___verify_get_ex_uint64_route@5: + // tests/artifacts/state-ops/contract.algo.ts:379 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:422 - // class StateAppGlobalContract(ARC4Contract): + 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/StateOps/contract.py:448 + // tests/artifacts/state-ops/contract.algo.ts:379 // @arc4.abimethod() callsub verify_get_ex_uint64 swap itob - byte 0x00 - int 0 + bytec_1 // 0x00 + intc_1 // 0 uncover 3 setbit concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_delete_route@6: - // tests/artifacts/StateOps/contract.py:452 +__puya_arc4_router___verify_put_uint64_route@6: + // tests/artifacts/state-ops/contract.algo.ts:384 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:422 - // class StateAppGlobalContract(ARC4Contract): + 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/StateOps/contract.py:452 + txna ApplicationArgs 2 + btoi + // tests/artifacts/state-ops/contract.algo.ts:384 // @arc4.abimethod() - callsub verify_delete - int 1 - return + callsub verify_put_uint64 + intc_0 // 1 + retsub -main_verify_put_uint64_route@7: - // tests/artifacts/StateOps/contract.py:456 +__puya_arc4_router___verify_put_bytes_route@7: + // tests/artifacts/state-ops/contract.algo.ts:389 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:422 - // class StateAppGlobalContract(ARC4Contract): + 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/StateOps/contract.py:456 + extract 2 0 + // tests/artifacts/state-ops/contract.algo.ts:389 // @arc4.abimethod() - callsub verify_put_uint64 - int 1 - return + callsub verify_put_bytes + intc_0 // 1 + retsub -main_verify_put_bytes_route@8: - // tests/artifacts/StateOps/contract.py:460 +__puya_arc4_router___verify_delete_route@8: + // tests/artifacts/state-ops/contract.algo.ts:394 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:422 - // class StateAppGlobalContract(ARC4Contract): + 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/StateOps/contract.py:460 + // tests/artifacts/state-ops/contract.algo.ts:394 // @arc4.abimethod() - callsub verify_put_bytes - int 1 - return + callsub verify_delete + intc_0 // 1 + retsub -main_bare_routing@11: - // tests/artifacts/StateOps/contract.py:422 - // class StateAppGlobalContract(ARC4Contract): +__puya_arc4_router___bare_routing@11: + // tests/artifacts/state-ops/contract.algo.ts:358 + // export class StateAppGlobalContract extends arc4.Contract { txn OnCompletion - ! - assert // reject transaction + bnz __puya_arc4_router___after_if_else@15 txn ApplicationID ! - assert // is creating - int 1 - return + 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.StateOps.contract.StateAppGlobalContract.verify_get_bytes(a: bytes) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_get_bytes(a: bytes) -> bytes: verify_get_bytes: - // tests/artifacts/StateOps/contract.py:434-435 + // tests/artifacts/state-ops/contract.algo.ts:362-363 // @arc4.abimethod() - // def verify_get_bytes(self, a: Bytes) -> Bytes: + // verify_get_bytes(a: bytes): bytes { proto 1 1 - // tests/artifacts/StateOps/contract.py:436 - // value = op.AppGlobal.get_bytes(a) + // tests/artifacts/state-ops/contract.algo.ts:364 + // const value = op.AppGlobal.getBytes(a) frame_dig -1 app_global_get - // tests/artifacts/StateOps/contract.py:437 + // tests/artifacts/state-ops/contract.algo.ts:365 // return value retsub -// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_get_uint64(a: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_get_uint64(a: bytes) -> uint64: verify_get_uint64: - // tests/artifacts/StateOps/contract.py:439-440 + // tests/artifacts/state-ops/contract.algo.ts:368-369 // @arc4.abimethod() - // def verify_get_uint64(self, a: Bytes) -> UInt64: + // verify_get_uint64(a: bytes): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:441 - // value = op.AppGlobal.get_uint64(a) + // tests/artifacts/state-ops/contract.algo.ts:370 + // const value = op.AppGlobal.getUint64(a) frame_dig -1 app_global_get - // tests/artifacts/StateOps/contract.py:442 + // tests/artifacts/state-ops/contract.algo.ts:371 // return value retsub -// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_get_ex_bytes(a: uint64, b: bytes) -> bytes, uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_get_ex_bytes(a: uint64, b: bytes) -> bytes, uint64: verify_get_ex_bytes: - // tests/artifacts/StateOps/contract.py:444-445 + // tests/artifacts/state-ops/contract.algo.ts:374-375 // @arc4.abimethod() - // def verify_get_ex_bytes(self, a: Application, b: Bytes) -> tuple[Bytes, bool]: + // verify_get_ex_bytes(a: Application, b: bytes): readonly [bytes, boolean] { proto 2 2 - // tests/artifacts/StateOps/contract.py:446 - // return op.AppGlobal.get_ex_bytes(a, b) + // 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.StateOps.contract.StateAppGlobalContract.verify_get_ex_uint64(a: uint64, b: bytes) -> uint64, uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_get_ex_uint64(a: uint64, b: bytes) -> uint64, uint64: verify_get_ex_uint64: - // tests/artifacts/StateOps/contract.py:448-449 + // tests/artifacts/state-ops/contract.algo.ts:379-380 // @arc4.abimethod() - // def verify_get_ex_uint64(self, a: Application, b: Bytes) -> tuple[UInt64, bool]: + // verify_get_ex_uint64(a: Application, b: bytes): readonly [uint64, boolean] { proto 2 2 - // tests/artifacts/StateOps/contract.py:450 - // return op.AppGlobal.get_ex_uint64(a, b) + // 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.StateOps.contract.StateAppGlobalContract.verify_delete(a: bytes) -> void: -verify_delete: - // tests/artifacts/StateOps/contract.py:452-453 - // @arc4.abimethod() - // def verify_delete(self, a: Bytes) -> None: - proto 1 0 - // tests/artifacts/StateOps/contract.py:454 - // op.AppGlobal.delete(a) - frame_dig -1 - app_global_del - retsub - - -// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_put_uint64(a: bytes, b: uint64) -> void: +// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_put_uint64(a: bytes, b: uint64) -> void: verify_put_uint64: - // tests/artifacts/StateOps/contract.py:456-457 + // tests/artifacts/state-ops/contract.algo.ts:384-385 // @arc4.abimethod() - // def verify_put_uint64(self, a: Bytes, b: UInt64) -> None: + // verify_put_uint64(a: bytes, b: uint64): void { proto 2 0 - // tests/artifacts/StateOps/contract.py:458 + // tests/artifacts/state-ops/contract.algo.ts:386 // op.AppGlobal.put(a, b) frame_dig -2 frame_dig -1 @@ -296,15 +291,28 @@ verify_put_uint64: retsub -// tests.artifacts.StateOps.contract.StateAppGlobalContract.verify_put_bytes(a: bytes, b: bytes) -> void: +// tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalContract.verify_put_bytes(a: bytes, b: bytes) -> void: verify_put_bytes: - // tests/artifacts/StateOps/contract.py:460-461 + // tests/artifacts/state-ops/contract.algo.ts:389-390 // @arc4.abimethod() - // def verify_put_bytes(self, a: Bytes, b: Bytes) -> None: + // verify_put_bytes(a: bytes, b: bytes): void { proto 2 0 - // tests/artifacts/StateOps/contract.py:462 + // 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 index 0f891de..479fa1b 100644 --- a/tests/artifacts/state-ops/data/StateAppGlobalContract.arc32.json +++ b/tests/artifacts/state-ops/data/StateAppGlobalContract.arc32.json @@ -20,25 +20,25 @@ "no_op": "CALL" } }, - "verify_delete(byte[])void": { + "verify_put_uint64(byte[],uint64)void": { "call_config": { "no_op": "CALL" } }, - "verify_put_uint64(byte[],uint64)void": { + "verify_put_bytes(byte[],byte[])void": { "call_config": { "no_op": "CALL" } }, - "verify_put_bytes(byte[],byte[])void": { + "verify_delete(byte[])void": { "call_config": { "no_op": "CALL" } } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDExCiAgICBtZXRob2QgInZlcmlmeV9nZXRfYnl0ZXMoYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF91aW50NjQoYnl0ZVtdKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF9leF9ieXRlcyhhcHBsaWNhdGlvbixieXRlW10pKGJ5dGVbXSxib29sKSIKICAgIG1ldGhvZCAidmVyaWZ5X2dldF9leF91aW50NjQoYXBwbGljYXRpb24sYnl0ZVtdKSh1aW50NjQsYm9vbCkiCiAgICBtZXRob2QgInZlcmlmeV9kZWxldGUoYnl0ZVtdKXZvaWQiCiAgICBtZXRob2QgInZlcmlmeV9wdXRfdWludDY0KGJ5dGVbXSx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X3B1dF9ieXRlcyhieXRlW10sYnl0ZVtdKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX3ZlcmlmeV9nZXRfYnl0ZXNfcm91dGVAMiBtYWluX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDMgbWFpbl92ZXJpZnlfZ2V0X2V4X2J5dGVzX3JvdXRlQDQgbWFpbl92ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1IG1haW5fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA2IG1haW5fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVANyBtYWluX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAOAogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfdWludDY0CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfZXhfYnl0ZXNfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDIyCiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0X2V4X2J5dGVzCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgwMDAzCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjIKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfdWludDY0CiAgICBzd2FwCiAgICBpdG9iCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDMKICAgIHNldGJpdAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9kZWxldGVfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDIyCiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2RlbGV0ZQogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjIKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X3VpbnQ2NAogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfcHV0X2J5dGVzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X2J5dGVzCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0AxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MjIKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfZ2V0X2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2dldF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzQtNDM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfYnl0ZXMoc2VsZiwgYTogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM2CiAgICAvLyB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRfYnl0ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MzcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X2dldF91aW50NjQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDM5LTQ0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X3VpbnQ2NChzZWxmLCBhOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQxCiAgICAvLyB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRfdWludDY0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDQyCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfYnl0ZXMoYTogdWludDY0LCBiOiBieXRlcykgLT4gYnl0ZXMsIHVpbnQ2NDoKdmVyaWZ5X2dldF9leF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDQtNDQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfYnl0ZXMoc2VsZiwgYTogQXBwbGljYXRpb24sIGI6IEJ5dGVzKSAtPiB0dXBsZVtCeXRlcywgYm9vbF06CiAgICBwcm90byAyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDYKICAgIC8vIHJldHVybiBvcC5BcHBHbG9iYWwuZ2V0X2V4X2J5dGVzKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfdWludDY0KGE6IHVpbnQ2NCwgYjogYnl0ZXMpIC0+IHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NDgtNDQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfdWludDY0KHNlbGYsIGE6IEFwcGxpY2F0aW9uLCBiOiBCeXRlcykgLT4gdHVwbGVbVUludDY0LCBib29sXToKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ1MAogICAgLy8gcmV0dXJuIG9wLkFwcEdsb2JhbC5nZXRfZXhfdWludDY0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9kZWxldGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDUyLTQ1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZGVsZXRlKHNlbGYsIGE6IEJ5dGVzKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDU0CiAgICAvLyBvcC5BcHBHbG9iYWwuZGVsZXRlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZGVsCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB2b2lkOgp2ZXJpZnlfcHV0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NTYtNDU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9wdXRfdWludDY0KHNlbGYsIGE6IEJ5dGVzLCBiOiBVSW50NjQpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0NTgKICAgIC8vIG9wLkFwcEdsb2JhbC5wdXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9wdXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDYwLTQ2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfcHV0X2J5dGVzKHNlbGYsIGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQ2MgogICAgLy8gb3AuQXBwR2xvYmFsLnB1dChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQyMgogICAgLy8gY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDEgMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1IDB4MDAKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBHbG9iYWxDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDExCiAgICBwdXNoYnl0ZXNzIDB4YTk5N2ExODcgMHg0ZGI4YWE0MSAweDY2OTNhYjkyIDB4ODU3ZmQ5MjMgMHgzNjk5NjQ1MSAweDM5MjBhNTdiIDB4OTNhODUyZTEgLy8gbWV0aG9kICJ2ZXJpZnlfZ2V0X2J5dGVzKGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9nZXRfdWludDY0KGJ5dGVbXSl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9nZXRfZXhfYnl0ZXMoYXBwbGljYXRpb24sYnl0ZVtdKShieXRlW10sYm9vbCkiLCBtZXRob2QgInZlcmlmeV9nZXRfZXhfdWludDY0KGFwcGxpY2F0aW9uLGJ5dGVbXSkodWludDY0LGJvb2wpIiwgbWV0aG9kICJ2ZXJpZnlfcHV0X3VpbnQ2NChieXRlW10sdWludDY0KXZvaWQiLCBtZXRob2QgInZlcmlmeV9wdXRfYnl0ZXMoYnl0ZVtdLGJ5dGVbXSl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfZGVsZXRlKGJ5dGVbXSl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9ieXRlc19yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcHV0X2J5dGVzX3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA4CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X3VpbnQ2NF9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfYnl0ZXMKICAgIGRpZyAxCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzEgLy8gMAogICAgdW5jb3ZlciAzCiAgICBzZXRiaXQKICAgIHB1c2hieXRlcyAweDAwMDMKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfdWludDY0CiAgICBzd2FwCiAgICBpdG9iCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDMKICAgIHNldGJpdAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X3VpbnQ2NAogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3B1dF9ieXRlc19yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3B1dF9ieXRlcwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZGVsZXRlCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBHbG9iYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTUKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X2dldF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9nZXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYyLTM2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9nZXRfYnl0ZXMoYTogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNjQKICAgIC8vIGNvbnN0IHZhbHVlID0gb3AuQXBwR2xvYmFsLmdldEJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzY1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfZ2V0X3VpbnQ2NChhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNjgtMzY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2dldF91aW50NjQoYTogYnl0ZXMpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzcwCiAgICAvLyBjb25zdCB2YWx1ZSA9IG9wLkFwcEdsb2JhbC5nZXRVaW50NjQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfYnl0ZXMoYTogdWludDY0LCBiOiBieXRlcykgLT4gYnl0ZXMsIHVpbnQ2NDoKdmVyaWZ5X2dldF9leF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNzQtMzc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2dldF9leF9ieXRlcyhhOiBBcHBsaWNhdGlvbiwgYjogYnl0ZXMpOiByZWFkb25seSBbYnl0ZXMsIGJvb2xlYW5dIHsKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM3NgogICAgLy8gcmV0dXJuIG9wLkFwcEdsb2JhbC5nZXRFeEJ5dGVzKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBHbG9iYWxDb250cmFjdC52ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhOiB1aW50NjQsIGI6IGJ5dGVzKSAtPiB1aW50NjQsIHVpbnQ2NDoKdmVyaWZ5X2dldF9leF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzc5LTM4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9nZXRfZXhfdWludDY0KGE6IEFwcGxpY2F0aW9uLCBiOiBieXRlcyk6IHJlYWRvbmx5IFt1aW50NjQsIGJvb2xlYW5dIHsKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4MQogICAgLy8gcmV0dXJuIG9wLkFwcEdsb2JhbC5nZXRFeFVpbnQ2NChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X3B1dF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdm9pZDoKdmVyaWZ5X3B1dF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg0LTM4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB2b2lkIHsKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4NgogICAgLy8gb3AuQXBwR2xvYmFsLnB1dChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9wdXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzg5LTM5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzKTogdm9pZCB7CiAgICBwcm90byAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozOTEKICAgIC8vIG9wLkFwcEdsb2JhbC5wdXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9kZWxldGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mzk0LTM5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9kZWxldGUoYTogYnl0ZXMpOiB2b2lkIHsKICAgIHByb3RvIDEgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5NgogICAgLy8gb3AuQXBwR2xvYmFsLmRlbGV0ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX2RlbAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" }, "state": { "global": { @@ -53,11 +53,11 @@ "schema": { "global": { "declared": { - "global_bytes": { + "globalBytes": { "type": "bytes", "key": "global_bytes" }, - "global_uint64": { + "globalUint64": { "type": "uint64", "key": "global_uint64" } @@ -133,11 +133,15 @@ } }, { - "name": "verify_delete", + "name": "verify_put_uint64", "args": [ { "type": "byte[]", "name": "a" + }, + { + "type": "uint64", + "name": "b" } ], "readonly": false, @@ -146,14 +150,14 @@ } }, { - "name": "verify_put_uint64", + "name": "verify_put_bytes", "args": [ { "type": "byte[]", "name": "a" }, { - "type": "uint64", + "type": "byte[]", "name": "b" } ], @@ -163,15 +167,11 @@ } }, { - "name": "verify_put_bytes", + "name": "verify_delete", "args": [ { "type": "byte[]", "name": "a" - }, - { - "type": "byte[]", - "name": "b" } ], "readonly": false, diff --git a/tests/artifacts/state-ops/data/StateAppGlobalContract.arc56.json b/tests/artifacts/state-ops/data/StateAppGlobalContract.arc56.json new file mode 100644 index 0000000..3d10bba --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppGlobalContract.arc56.json @@ -0,0 +1,260 @@ +{ + "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 index d7a1245..62c9330 100644 --- a/tests/artifacts/state-ops/data/StateAppGlobalContract.clear.teal +++ b/tests/artifacts/state-ops/data/StateAppGlobalContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAppGlobalContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:422 - // class StateAppGlobalContract(ARC4Contract): - int 1 +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 index 35af159..bc81e3d 100644 --- a/tests/artifacts/state-ops/data/StateAppGlobalExContract.approval.teal +++ b/tests/artifacts/state-ops/data/StateAppGlobalExContract.approval.teal @@ -1,77 +1,71 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAppGlobalExContract.approval_program: +tests/artifacts/state-ops/contract.algo.ts::StateAppGlobalExContract.approvalProgram: + bytecblock "dummy_bytes" 0x001064756d6d795f617263345f6279746573 txn ApplicationID - bnz main_entrypoint@2 - callsub __init__ + bnz main_after_if_else@2 + callsub constructor -main_entrypoint@2: - // tests/artifacts/StateOps/contract.py:404 - // class StateAppGlobalExContract(ARC4Contract): - txn NumAppArgs - ! - assert // reject transaction - txn OnCompletion - ! - assert // reject transaction - txn ApplicationID - ! - assert // is creating - int 1 +main_after_if_else@2: + callsub __puya_arc4_router__ return -// tests.artifacts.StateOps.contract.StateAppGlobalExContract.__init__() -> void: -__init__: - // tests/artifacts/StateOps/contract.py:405 - // def __init__(self) -> None: +// 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/StateOps/contract.py:408 - // key="global_uint64", - byte "global_uint64" - // tests/artifacts/StateOps/contract.py:407 - // UInt64(2), - int 2 - // tests/artifacts/StateOps/contract.py:406-409 - // self.global_uint64 = GlobalState( - // UInt64(2), - // key="global_uint64", - // ) + // 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/StateOps/contract.py:412 - // key="global_bytes", - byte "global_bytes" - // tests/artifacts/StateOps/contract.py:411 - // Bytes(b"dummy_bytes"), - byte 0x64756d6d795f6279746573 - // tests/artifacts/StateOps/contract.py:410-413 - // self.global_bytes = GlobalState( - // Bytes(b"dummy_bytes"), - // key="global_bytes", - // ) + // 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/StateOps/contract.py:414 - // self.global_uint64_explicit = algopy.UInt64(2) - byte "global_uint64_explicit" - int 2 + // 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/StateOps/contract.py:415 - // self.global_bytes_explicit = algopy.Bytes(b"dummy_bytes") - byte "global_bytes_explicit" - byte 0x64756d6d795f6279746573 + // 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/StateOps/contract.py:417 - // algopy.arc4.DynamicBytes(b"dummy_arc4_bytes"), key="global_arc4_bytes" - byte "global_arc4_bytes" - byte 0x001064756d6d795f617263345f6279746573 - // tests/artifacts/StateOps/contract.py:416-418 - // self.global_arc4_bytes = GlobalState( - // algopy.arc4.DynamicBytes(b"dummy_arc4_bytes"), key="global_arc4_bytes" - // ) + // 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/StateOps/contract.py:419 - // self.global_arc4_bytes_explicit = algopy.arc4.DynamicBytes(b"dummy_arc4_bytes") - byte "global_arc4_bytes_explicit" - byte 0x001064756d6d795f617263345f6279746573 + // 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 index 4492dbf..4e8e5d8 100644 --- a/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc32.json +++ b/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc32.json @@ -1,8 +1,8 @@ { "hints": {}, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDQKICAgIC8vIGNsYXNzIFN0YXRlQXBwR2xvYmFsRXhDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0Ll9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA1CiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQwOAogICAgLy8ga2V5PSJnbG9iYWxfdWludDY0IiwKICAgIGJ5dGUgImdsb2JhbF91aW50NjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA3CiAgICAvLyBVSW50NjQoMiksCiAgICBpbnQgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjQwNi00MDkKICAgIC8vIHNlbGYuZ2xvYmFsX3VpbnQ2NCA9IEdsb2JhbFN0YXRlKAogICAgLy8gICAgIFVJbnQ2NCgyKSwKICAgIC8vICAgICBrZXk9Imdsb2JhbF91aW50NjQiLAogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTIKICAgIC8vIGtleT0iZ2xvYmFsX2J5dGVzIiwKICAgIGJ5dGUgImdsb2JhbF9ieXRlcyIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTEKICAgIC8vIEJ5dGVzKGIiZHVtbXlfYnl0ZXMiKSwKICAgIGJ5dGUgMHg2NDc1NmQ2ZDc5NWY2Mjc5NzQ2NTczCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDEwLTQxMwogICAgLy8gc2VsZi5nbG9iYWxfYnl0ZXMgPSBHbG9iYWxTdGF0ZSgKICAgIC8vICAgICBCeXRlcyhiImR1bW15X2J5dGVzIiksCiAgICAvLyAgICAga2V5PSJnbG9iYWxfYnl0ZXMiLAogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTQKICAgIC8vIHNlbGYuZ2xvYmFsX3VpbnQ2NF9leHBsaWNpdCA9IGFsZ29weS5VSW50NjQoMikKICAgIGJ5dGUgImdsb2JhbF91aW50NjRfZXhwbGljaXQiCiAgICBpbnQgMgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTUKICAgIC8vIHNlbGYuZ2xvYmFsX2J5dGVzX2V4cGxpY2l0ID0gYWxnb3B5LkJ5dGVzKGIiZHVtbXlfYnl0ZXMiKQogICAgYnl0ZSAiZ2xvYmFsX2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZSAweDY0NzU2ZDZkNzk1ZjYyNzk3NDY1NzMKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDE3CiAgICAvLyBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoYiJkdW1teV9hcmM0X2J5dGVzIiksIGtleT0iZ2xvYmFsX2FyYzRfYnl0ZXMiCiAgICBieXRlICJnbG9iYWxfYXJjNF9ieXRlcyIKICAgIGJ5dGUgMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTYtNDE4CiAgICAvLyBzZWxmLmdsb2JhbF9hcmM0X2J5dGVzID0gR2xvYmFsU3RhdGUoCiAgICAvLyAgICAgYWxnb3B5LmFyYzQuRHluYW1pY0J5dGVzKGIiZHVtbXlfYXJjNF9ieXRlcyIpLCBrZXk9Imdsb2JhbF9hcmM0X2J5dGVzIgogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MTkKICAgIC8vIHNlbGYuZ2xvYmFsX2FyYzRfYnl0ZXNfZXhwbGljaXQgPSBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoYiJkdW1teV9hcmM0X2J5dGVzIikKICAgIGJ5dGUgImdsb2JhbF9hcmM0X2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZSAweDAwMTA2NDc1NmQ2ZDc5NWY2MTcyNjMzNDVmNjI3OTc0NjU3MwogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBHbG9iYWxFeENvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6NDA0CiAgICAvLyBjbGFzcyBTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsRXhDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBieXRlY2Jsb2NrICJkdW1teV9ieXRlcyIgMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9hZnRlcl9pZl9lbHNlQDIKICAgIGNhbGxzdWIgY29uc3RydWN0b3IKCm1haW5fYWZ0ZXJfaWZfZWxzZUAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QuY29uc3RydWN0b3IoKSAtPiB2b2lkOgpjb25zdHJ1Y3RvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1MAogICAgLy8gZ2xvYmFsVWludDY0ID0gR2xvYmFsU3RhdGUoeyBrZXk6IEJ5dGVzKCdnbG9iYWxfdWludDY0JyksIGluaXRpYWxWYWx1ZTogVWludDY0KDIpIH0pCiAgICBwdXNoYnl0ZXMgImdsb2JhbF91aW50NjQiCiAgICBwdXNoaW50IDIgLy8gMgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNTEKICAgIC8vIGdsb2JhbEJ5dGVzID0gR2xvYmFsU3RhdGUoeyBrZXk6IEJ5dGVzKCdnbG9iYWxfYnl0ZXMnKSwgaW5pdGlhbFZhbHVlOiBCeXRlcygnZHVtbXlfYnl0ZXMnKSB9KQogICAgcHVzaGJ5dGVzICJnbG9iYWxfYnl0ZXMiCiAgICBieXRlY18wIC8vICJkdW1teV9ieXRlcyIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUyCiAgICAvLyBnbG9iYWxfdWludDY0X2V4cGxpY2l0ID0gR2xvYmFsU3RhdGUoeyBpbml0aWFsVmFsdWU6IFVpbnQ2NCgyKSB9KQogICAgcHVzaGJ5dGVzICJnbG9iYWxfdWludDY0X2V4cGxpY2l0IgogICAgcHVzaGludCAyIC8vIDIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUzCiAgICAvLyBnbG9iYWxfYnl0ZXNfZXhwbGljaXQgPSBHbG9iYWxTdGF0ZSh7IGluaXRpYWxWYWx1ZTogQnl0ZXMoJ2R1bW15X2J5dGVzJykgfSkKICAgIHB1c2hieXRlcyAiZ2xvYmFsX2J5dGVzX2V4cGxpY2l0IgogICAgYnl0ZWNfMCAvLyAiZHVtbXlfYnl0ZXMiCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1NAogICAgLy8gZ2xvYmFsQXJjNEJ5dGVzID0gR2xvYmFsU3RhdGUoeyBrZXk6IEJ5dGVzKCdnbG9iYWxfYXJjNF9ieXRlcycpLCBpbml0aWFsVmFsdWU6IG5ldyBEeW5hbWljQnl0ZXMoJ2R1bW15X2FyYzRfYnl0ZXMnKSB9KQogICAgcHVzaGJ5dGVzICJnbG9iYWxfYXJjNF9ieXRlcyIKICAgIGJ5dGVjXzEgLy8gMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzU1CiAgICAvLyBnbG9iYWxfYXJjNF9ieXRlc19leHBsaWNpdCA9IEdsb2JhbFN0YXRlKHsgaW5pdGlhbFZhbHVlOiBuZXcgRHluYW1pY0J5dGVzKCdkdW1teV9hcmM0X2J5dGVzJykgfSkKICAgIHB1c2hieXRlcyAiZ2xvYmFsX2FyYzRfYnl0ZXNfZXhwbGljaXQiCiAgICBieXRlY18xIC8vIDB4MDAxMDY0NzU2ZDZkNzk1ZjYxNzI2MzM0NWY2Mjc5NzQ2NTczCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0OQogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwR2xvYmFsRXhDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDkKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcEdsb2JhbEV4Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHB1c2hpbnQgMCAvLyAwCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwR2xvYmFsRXhDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" }, "state": { "global": { @@ -17,26 +17,26 @@ "schema": { "global": { "declared": { - "global_arc4_bytes": { + "globalArc4Bytes": { "type": "bytes", "key": "global_arc4_bytes" }, - "global_arc4_bytes_explicit": { + "globalBytes": { "type": "bytes", - "key": "global_arc4_bytes_explicit" + "key": "global_bytes" + }, + "globalUint64": { + "type": "uint64", + "key": "global_uint64" }, - "global_bytes": { + "global_arc4_bytes_explicit": { "type": "bytes", - "key": "global_bytes" + "key": "global_arc4_bytes_explicit" }, "global_bytes_explicit": { "type": "bytes", "key": "global_bytes_explicit" }, - "global_uint64": { - "type": "uint64", - "key": "global_uint64" - }, "global_uint64_explicit": { "type": "uint64", "key": "global_uint64_explicit" diff --git a/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc56.json b/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc56.json new file mode 100644 index 0000000..2f5a1d0 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppGlobalExContract.arc56.json @@ -0,0 +1,92 @@ +{ + "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 index 3d0e5c8..c5063ae 100644 --- a/tests/artifacts/state-ops/data/StateAppGlobalExContract.clear.teal +++ b/tests/artifacts/state-ops/data/StateAppGlobalExContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAppGlobalExContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:404 - // class StateAppGlobalExContract(ARC4Contract): - int 1 +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 index d373649..e9aa093 100644 --- a/tests/artifacts/state-ops/data/StateAppLocalContract.approval.teal +++ b/tests/artifacts/state-ops/data/StateAppLocalContract.approval.teal @@ -1,52 +1,54 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAppLocalContract.approval_program: - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): +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 main_bare_routing@13 - method "opt_in()void" - method "verify_get_bytes(account,byte[])byte[]" - method "verify_get_uint64(account,byte[])uint64" - method "verify_get_ex_bytes(account,application,byte[])byte[]" - method "verify_get_ex_uint64(account,application,byte[])uint64" - method "verify_delete(account,byte[])void" - method "verify_exists(account,byte[])bool" - method "verify_put_uint64(account,byte[],uint64)void" - method "verify_put_bytes(account,byte[],byte[])void" + 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 main_opt_in_route@2 main_verify_get_bytes_route@3 main_verify_get_uint64_route@4 main_verify_get_ex_bytes_route@5 main_verify_get_ex_uint64_route@6 main_verify_delete_route@7 main_verify_exists_route@8 main_verify_put_uint64_route@9 main_verify_put_bytes_route@10 - err // reject transaction + 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 -main_opt_in_route@2: - // tests/artifacts/StateOps/contract.py:361 - // @arc4.abimethod(allow_actions=["OptIn"]) +__puya_arc4_router___opt_in_route@2: + // tests/artifacts/state-ops/contract.algo.ts:417 + // @arc4.abimethod({ allowActions: ['OptIn'] }) txn OnCompletion - int OptIn + intc_0 // OptIn == - assert // OnCompletion is OptIn + assert // OnCompletion is not OptIn txn ApplicationID - assert // is not creating + assert // can only call when not creating callsub opt_in - int 1 - return + intc_0 // 1 + retsub -main_verify_get_bytes_route@3: - // tests/artifacts/StateOps/contract.py:366 +__puya_arc4_router___verify_get_bytes_route@3: + // tests/artifacts/state-ops/contract.algo.ts:423 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): + 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/StateOps/contract.py:366 + // tests/artifacts/state-ops/contract.algo.ts:423 // @arc4.abimethod() callsub verify_get_bytes dup @@ -55,49 +57,49 @@ main_verify_get_bytes_route@3: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_get_uint64_route@4: - // tests/artifacts/StateOps/contract.py:371 +__puya_arc4_router___verify_get_uint64_route@4: + // tests/artifacts/state-ops/contract.algo.ts:429 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): + 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/StateOps/contract.py:371 + // tests/artifacts/state-ops/contract.algo.ts:429 // @arc4.abimethod() callsub verify_get_uint64 itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_get_ex_bytes_route@5: - // tests/artifacts/StateOps/contract.py:376 +__puya_arc4_router___verify_get_ex_bytes_route@5: + // tests/artifacts/state-ops/contract.algo.ts:435 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): + 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 @@ -106,7 +108,7 @@ main_verify_get_ex_bytes_route@5: txnas Applications txna ApplicationArgs 3 extract 2 0 - // tests/artifacts/StateOps/contract.py:376 + // tests/artifacts/state-ops/contract.algo.ts:435 // @arc4.abimethod() callsub verify_get_ex_bytes dup @@ -115,23 +117,23 @@ main_verify_get_ex_bytes_route@5: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_get_ex_uint64_route@6: - // tests/artifacts/StateOps/contract.py:381 +__puya_arc4_router___verify_get_ex_uint64_route@6: + // tests/artifacts/state-ops/contract.algo.ts:441 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): + 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 @@ -140,77 +142,77 @@ main_verify_get_ex_uint64_route@6: txnas Applications txna ApplicationArgs 3 extract 2 0 - // tests/artifacts/StateOps/contract.py:381 + // tests/artifacts/state-ops/contract.algo.ts:441 // @arc4.abimethod() callsub verify_get_ex_uint64 itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_delete_route@7: - // tests/artifacts/StateOps/contract.py:386 +__puya_arc4_router___verify_delete_route@7: + // tests/artifacts/state-ops/contract.algo.ts:447 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): + 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/StateOps/contract.py:386 + // tests/artifacts/state-ops/contract.algo.ts:447 // @arc4.abimethod() callsub verify_delete - int 1 - return + intc_0 // 1 + retsub -main_verify_exists_route@8: - // tests/artifacts/StateOps/contract.py:390 +__puya_arc4_router___verify_exists_route@8: + // tests/artifacts/state-ops/contract.algo.ts:452 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): + 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/StateOps/contract.py:390 + // tests/artifacts/state-ops/contract.algo.ts:452 // @arc4.abimethod() callsub verify_exists - byte 0x00 - int 0 + pushbytes 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_put_uint64_route@9: - // tests/artifacts/StateOps/contract.py:395 +__puya_arc4_router___verify_put_uint64_route@9: + // tests/artifacts/state-ops/contract.algo.ts:458 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): + 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 @@ -218,22 +220,22 @@ main_verify_put_uint64_route@9: extract 2 0 txna ApplicationArgs 3 btoi - // tests/artifacts/StateOps/contract.py:395 + // tests/artifacts/state-ops/contract.algo.ts:458 // @arc4.abimethod() callsub verify_put_uint64 - int 1 - return + intc_0 // 1 + retsub -main_verify_put_bytes_route@10: - // tests/artifacts/StateOps/contract.py:399 +__puya_arc4_router___verify_put_bytes_route@10: + // tests/artifacts/state-ops/contract.algo.ts:463 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): + 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 @@ -241,129 +243,133 @@ main_verify_put_bytes_route@10: extract 2 0 txna ApplicationArgs 3 extract 2 0 - // tests/artifacts/StateOps/contract.py:399 + // tests/artifacts/state-ops/contract.algo.ts:463 // @arc4.abimethod() callsub verify_put_bytes - int 1 - return + intc_0 // 1 + retsub -main_bare_routing@13: - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): +__puya_arc4_router___bare_routing@13: + // tests/artifacts/state-ops/contract.algo.ts:413 + // export class StateAppLocalContract extends arc4.Contract { txn OnCompletion - ! - assert // reject transaction + bnz __puya_arc4_router___after_if_else@17 txn ApplicationID ! - assert // is creating - int 1 - return + 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.StateOps.contract.StateAppLocalContract.opt_in() -> void: +// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.opt_in() -> void: opt_in: - // tests/artifacts/StateOps/contract.py:361-362 - // @arc4.abimethod(allow_actions=["OptIn"]) - // def opt_in(self) -> None: + // tests/artifacts/state-ops/contract.algo.ts:417-418 + // @arc4.abimethod({ allowActions: ['OptIn'] }) + // opt_in() { proto 0 0 - // tests/artifacts/StateOps/contract.py:363 - // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes") + // tests/artifacts/state-ops/contract.algo.ts:419 + // this.localBytes(Global.creatorAddress).value = Bytes('dummy_bytes') global CreatorAddress - // tests/artifacts/StateOps/contract.py:358 - // key="local_bytes", - byte "local_bytes" - // tests/artifacts/StateOps/contract.py:363 - // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes") - byte 0x64756d6d795f6279746573 + // 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/StateOps/contract.py:364 - // self.local_uint64[Global.creator_address] = UInt64(999) + // tests/artifacts/state-ops/contract.algo.ts:420 + // this.localUint64(Global.creatorAddress).value = Uint64(999) global CreatorAddress - // tests/artifacts/StateOps/contract.py:353 - // key="local_uint64", - byte "local_uint64" - // tests/artifacts/StateOps/contract.py:364 - // self.local_uint64[Global.creator_address] = UInt64(999) - int 999 + // 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.StateOps.contract.StateAppLocalContract.verify_get_bytes(a: bytes, b: bytes) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_get_bytes(a: bytes, b: bytes) -> bytes: verify_get_bytes: - // tests/artifacts/StateOps/contract.py:366-367 + // tests/artifacts/state-ops/contract.algo.ts:423-424 // @arc4.abimethod() - // def verify_get_bytes(self, a: Account, b: Bytes) -> Bytes: + // verify_get_bytes(a: Account, b: bytes): bytes { proto 2 1 - // tests/artifacts/StateOps/contract.py:368 - // value = op.AppLocal.get_bytes(a, b) + // 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/StateOps/contract.py:369 + // tests/artifacts/state-ops/contract.algo.ts:426 // return value retsub -// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_uint64(a: bytes, b: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_get_uint64(a: bytes, b: bytes) -> uint64: verify_get_uint64: - // tests/artifacts/StateOps/contract.py:371-372 + // tests/artifacts/state-ops/contract.algo.ts:429-430 // @arc4.abimethod() - // def verify_get_uint64(self, a: Account, b: Bytes) -> UInt64: + // verify_get_uint64(a: Account, b: bytes): uint64 { proto 2 1 - // tests/artifacts/StateOps/contract.py:373 - // value = op.AppLocal.get_uint64(a, b) + // 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/StateOps/contract.py:374 + // tests/artifacts/state-ops/contract.algo.ts:432 // return value retsub -// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_ex_bytes(a: bytes, b: uint64, c: bytes) -> bytes: +// 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/StateOps/contract.py:376-377 + // tests/artifacts/state-ops/contract.algo.ts:435-436 // @arc4.abimethod() - // def verify_get_ex_bytes(self, a: Account, b: Application, c: Bytes) -> Bytes: + // verify_get_ex_bytes(a: Account, b: Application, c: bytes): bytes { proto 3 1 - // tests/artifacts/StateOps/contract.py:378 - // value, _val = op.AppLocal.get_ex_bytes(a, b, c) + // 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/StateOps/contract.py:379 + // tests/artifacts/state-ops/contract.algo.ts:438 // return value retsub -// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_get_ex_uint64(a: bytes, b: uint64, c: bytes) -> uint64: +// 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/StateOps/contract.py:381-382 + // tests/artifacts/state-ops/contract.algo.ts:441-442 // @arc4.abimethod() - // def verify_get_ex_uint64(self, a: Account, b: Application, c: Bytes) -> UInt64: + // verify_get_ex_uint64(a: Account, b: Application, c: bytes): uint64 { proto 3 1 - // tests/artifacts/StateOps/contract.py:383 - // value, _val = op.AppLocal.get_ex_uint64(a, b, c) + // 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/StateOps/contract.py:384 + // tests/artifacts/state-ops/contract.algo.ts:444 // return value retsub -// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_delete(a: bytes, b: bytes) -> void: +// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_delete(a: bytes, b: bytes) -> void: verify_delete: - // tests/artifacts/StateOps/contract.py:386-387 + // tests/artifacts/state-ops/contract.algo.ts:447-448 // @arc4.abimethod() - // def verify_delete(self, a: Account, b: Bytes) -> None: + // verify_delete(a: Account, b: bytes): void { proto 2 0 - // tests/artifacts/StateOps/contract.py:388 + // tests/artifacts/state-ops/contract.algo.ts:449 // op.AppLocal.delete(a, b) frame_dig -2 frame_dig -1 @@ -371,31 +377,31 @@ verify_delete: retsub -// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_exists(a: bytes, b: bytes) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_exists(a: bytes, b: bytes) -> uint64: verify_exists: - // tests/artifacts/StateOps/contract.py:390-391 + // tests/artifacts/state-ops/contract.algo.ts:452-453 // @arc4.abimethod() - // def verify_exists(self, a: Account, b: Bytes) -> bool: + // verify_exists(a: Account, b: bytes): boolean { proto 2 1 - // tests/artifacts/StateOps/contract.py:392 - // _value, exists = op.AppLocal.get_ex_uint64(a, 0, b) + // tests/artifacts/state-ops/contract.algo.ts:454 + // const [_value, exists] = op.AppLocal.getExUint64(a, 0, b) frame_dig -2 - int 0 + intc_1 // 0 frame_dig -1 app_local_get_ex bury 1 - // tests/artifacts/StateOps/contract.py:393 + // tests/artifacts/state-ops/contract.algo.ts:455 // return exists retsub -// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_put_uint64(a: bytes, b: bytes, c: uint64) -> void: +// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_put_uint64(a: bytes, b: bytes, c: uint64) -> void: verify_put_uint64: - // tests/artifacts/StateOps/contract.py:395-396 + // tests/artifacts/state-ops/contract.algo.ts:458-459 // @arc4.abimethod() - // def verify_put_uint64(self, a: Account, b: Bytes, c: UInt64) -> None: + // verify_put_uint64(a: Account, b: bytes, c: uint64): void { proto 3 0 - // tests/artifacts/StateOps/contract.py:397 + // tests/artifacts/state-ops/contract.algo.ts:460 // op.AppLocal.put(a, b, c) frame_dig -3 frame_dig -2 @@ -404,13 +410,13 @@ verify_put_uint64: retsub -// tests.artifacts.StateOps.contract.StateAppLocalContract.verify_put_bytes(a: bytes, b: bytes, c: bytes) -> void: +// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalContract.verify_put_bytes(a: bytes, b: bytes, c: bytes) -> void: verify_put_bytes: - // tests/artifacts/StateOps/contract.py:399-400 + // tests/artifacts/state-ops/contract.algo.ts:463-464 // @arc4.abimethod() - // def verify_put_bytes(self, a: Account, b: Bytes, c: Bytes) -> None: + // verify_put_bytes(a: Account, b: bytes, c: bytes): void { proto 3 0 - // tests/artifacts/StateOps/contract.py:401 + // tests/artifacts/state-ops/contract.algo.ts:465 // op.AppLocal.put(a, b, c) frame_dig -3 frame_dig -2 diff --git a/tests/artifacts/state-ops/data/StateAppLocalContract.arc32.json b/tests/artifacts/state-ops/data/StateAppLocalContract.arc32.json index f5ed19a..01fc23d 100644 --- a/tests/artifacts/state-ops/data/StateAppLocalContract.arc32.json +++ b/tests/artifacts/state-ops/data/StateAppLocalContract.arc32.json @@ -47,8 +47,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxMwogICAgbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICBtZXRob2QgInZlcmlmeV9nZXRfYnl0ZXMoYWNjb3VudCxieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZ2V0X3VpbnQ2NChhY2NvdW50LGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9nZXRfZXhfYnl0ZXMoYWNjb3VudCxhcHBsaWNhdGlvbixieXRlW10pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhY2NvdW50LGFwcGxpY2F0aW9uLGJ5dGVbXSl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9kZWxldGUoYWNjb3VudCxieXRlW10pdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X2V4aXN0cyhhY2NvdW50LGJ5dGVbXSlib29sIgogICAgbWV0aG9kICJ2ZXJpZnlfcHV0X3VpbnQ2NChhY2NvdW50LGJ5dGVbXSx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAidmVyaWZ5X3B1dF9ieXRlcyhhY2NvdW50LGJ5dGVbXSxieXRlW10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fb3B0X2luX3JvdXRlQDIgbWFpbl92ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDMgbWFpbl92ZXJpZnlfZ2V0X3VpbnQ2NF9yb3V0ZUA0IG1haW5fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1IG1haW5fdmVyaWZ5X2dldF9leF91aW50NjRfcm91dGVANiBtYWluX3ZlcmlmeV9kZWxldGVfcm91dGVANyBtYWluX3ZlcmlmeV9leGlzdHNfcm91dGVAOCBtYWluX3ZlcmlmeV9wdXRfdWludDY0X3JvdXRlQDkgbWFpbl92ZXJpZnlfcHV0X2J5dGVzX3JvdXRlQDEwCiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBPcHRJbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfYnl0ZXNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldF91aW50NjRfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDkKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0OQogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldF9leF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDkKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZGVsZXRlCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9leGlzdHNfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4aXN0cwogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3B1dF91aW50NjQKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X3B1dF9ieXRlc19yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9wdXRfYnl0ZXMKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0OQogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC5vcHRfaW4oKSAtPiB2b2lkOgpvcHRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYxLTM2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgLy8gZGVmIG9wdF9pbihzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYzCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlcyIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNTgKICAgIC8vIGtleT0ibG9jYWxfYnl0ZXMiLAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzYzCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlcyIpCiAgICBieXRlIDB4NjQ3NTZkNmQ3OTVmNjI3OTc0NjU3MwogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM2NAogICAgLy8gc2VsZi5sb2NhbF91aW50NjRbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBVSW50NjQoOTk5KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzUzCiAgICAvLyBrZXk9ImxvY2FsX3VpbnQ2NCIsCiAgICBieXRlICJsb2NhbF91aW50NjQiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY0CiAgICAvLyBzZWxmLmxvY2FsX3VpbnQ2NFtHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IFVJbnQ2NCg5OTkpCiAgICBpbnQgOTk5CiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9nZXRfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2dldF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjYtMzY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfYnl0ZXMoc2VsZiwgYTogQWNjb3VudCwgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzY4CiAgICAvLyB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldF9ieXRlcyhhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNjkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzcxLTM3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X3VpbnQ2NChzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzczCiAgICAvLyB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldF91aW50NjQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzc0CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2dldF9leF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9nZXRfZXhfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzc2LTM3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfZ2V0X2V4X2J5dGVzKHNlbGYsIGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzgKICAgIC8vIHZhbHVlLCBfdmFsID0gb3AuQXBwTG9jYWwuZ2V0X2V4X2J5dGVzKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNzkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozODEtMzgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9nZXRfZXhfdWludDY0KHNlbGYsIGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBCeXRlcykgLT4gVUludDY0OgogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzgzCiAgICAvLyB2YWx1ZSwgX3ZhbCA9IG9wLkFwcExvY2FsLmdldF9leF91aW50NjQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4NAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9kZWxldGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB2b2lkOgp2ZXJpZnlfZGVsZXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4Ni0zODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2RlbGV0ZShzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM4OAogICAgLy8gb3AuQXBwTG9jYWwuZGVsZXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2RlbAogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZXhpc3RzKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZXhpc3RzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5MC0zOTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2V4aXN0cyhzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcykgLT4gYm9vbDoKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5MgogICAgLy8gX3ZhbHVlLCBleGlzdHMgPSBvcC5BcHBMb2NhbC5nZXRfZXhfdWludDY0KGEsIDAsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5MwogICAgLy8gcmV0dXJuIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCkgLT4gdm9pZDoKdmVyaWZ5X3B1dF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzk1LTM5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfcHV0X3VpbnQ2NChzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcywgYzogVUludDY0KSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mzk3CiAgICAvLyBvcC5BcHBMb2NhbC5wdXQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X3B1dF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzKSAtPiB2b2lkOgp2ZXJpZnlfcHV0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM5OS00MDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X3B1dF9ieXRlcyhzZWxmLCBhOiBBY2NvdW50LCBiOiBCeXRlcywgYzogQnl0ZXMpIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTo0MDEKICAgIC8vIG9wLkFwcExvY2FsLnB1dChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbENvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ5CiAgICAvLyBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBMb2NhbENvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTMKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMwogICAgcHVzaGJ5dGVzcyAweDMwYzZkNThhIDB4OTM3YjVlMTMgMHg4ZDc0MmI4NiAweDdhNmQwYjU5IDB4NTk0ZmYxZDkgMHg5NWEzMTcyNyAweGFhMWY0NzkyIDB4NDYyNDUyODcgMHg3ZjBmZGZkZCAvLyBtZXRob2QgIm9wdF9pbigpdm9pZCIsIG1ldGhvZCAidmVyaWZ5X2dldF9ieXRlcyhhY2NvdW50LGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9nZXRfdWludDY0KGFjY291bnQsYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2dldF9leF9ieXRlcyhhY2NvdW50LGFwcGxpY2F0aW9uLGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9nZXRfZXhfdWludDY0KGFjY291bnQsYXBwbGljYXRpb24sYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2RlbGV0ZShhY2NvdW50LGJ5dGVbXSl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfZXhpc3RzKGFjY291bnQsYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9wdXRfdWludDY0KGFjY291bnQsYnl0ZVtdLHVpbnQ2NCl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfcHV0X2J5dGVzKGFjY291bnQsYnl0ZVtdLGJ5dGVbXSl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2luX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9ieXRlc19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfdWludDY0X3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRfZXhfdWludDY0X3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2RlbGV0ZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leGlzdHNfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcHV0X3VpbnQ2NF9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAMTAKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHsgYWxsb3dBY3Rpb25zOiBbJ09wdEluJ10gfSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludGNfMCAvLyBPcHRJbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE9wdEluCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2J5dGVzX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X3VpbnQ2NF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxMwogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldF9leF9ieXRlc19yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxMwogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0X2V4X3VpbnQ2NF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxMwogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRfZXhfdWludDY0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZGVsZXRlX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9kZWxldGUKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leGlzdHNfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTMKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4aXN0cwogICAgcHVzaGJ5dGVzIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3B1dF91aW50NjRfcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTMKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcExvY2FsQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3B1dF91aW50NjQKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9wdXRfYnl0ZXNfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfcHV0X2J5dGVzCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxNwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDEzCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBMb2NhbENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3Qub3B0X2luKCkgLT4gdm9pZDoKb3B0X2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxNy00MTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCh7IGFsbG93QWN0aW9uczogWydPcHRJbiddIH0pCiAgICAvLyBvcHRfaW4oKSB7CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MTkKICAgIC8vIHRoaXMubG9jYWxCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gQnl0ZXMoJ2R1bW15X2J5dGVzJykKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxNQogICAgLy8gbG9jYWxCeXRlcyA9IExvY2FsU3RhdGU8Ynl0ZXM+KHsga2V5OiAnbG9jYWxfYnl0ZXMnIH0pCiAgICBwdXNoYnl0ZXNzICJsb2NhbF9ieXRlcyIgImR1bW15X2J5dGVzIiAvLyAibG9jYWxfYnl0ZXMiLCAiZHVtbXlfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDE5CiAgICAvLyB0aGlzLmxvY2FsQnl0ZXMoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IEJ5dGVzKCdkdW1teV9ieXRlcycpCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIwCiAgICAvLyB0aGlzLmxvY2FsVWludDY0KEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBVaW50NjQoOTk5KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDE0CiAgICAvLyBsb2NhbFVpbnQ2NCA9IExvY2FsU3RhdGU8dWludDY0Pih7IGtleTogJ2xvY2FsX3VpbnQ2NCcgfSkKICAgIHB1c2hieXRlcyAibG9jYWxfdWludDY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyMAogICAgLy8gdGhpcy5sb2NhbFVpbnQ2NChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gVWludDY0KDk5OSkKICAgIHB1c2hpbnQgOTk5IC8vIDk5OQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2dldF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfZ2V0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyMy00MjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyB2ZXJpZnlfZ2V0X2J5dGVzKGE6IEFjY291bnQsIGI6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDI1CiAgICAvLyBjb25zdCB2YWx1ZSA9IG9wLkFwcExvY2FsLmdldEJ5dGVzKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2dldAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyNgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDI5LTQzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9nZXRfdWludDY0KGE6IEFjY291bnQsIGI6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzMQogICAgLy8gY29uc3QgdmFsdWUgPSBvcC5BcHBMb2NhbC5nZXRVaW50NjQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMyCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBMb2NhbENvbnRyYWN0LnZlcmlmeV9nZXRfZXhfYnl0ZXMoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfZ2V0X2V4X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzNS00MzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyB2ZXJpZnlfZ2V0X2V4X2J5dGVzKGE6IEFjY291bnQsIGI6IEFwcGxpY2F0aW9uLCBjOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzNwogICAgLy8gY29uc3QgW3ZhbHVlLCBfdmFsXSA9IG9wLkFwcExvY2FsLmdldEV4Qnl0ZXMoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzOAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfZ2V0X2V4X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0LCBjOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0X2V4X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDEtNDQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2dldF9leF91aW50NjQoYTogQWNjb3VudCwgYjogQXBwbGljYXRpb24sIGM6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0MwogICAgLy8gY29uc3QgW3ZhbHVlLCBfdmFsXSA9IG9wLkFwcExvY2FsLmdldEV4VWludDY0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NDQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2RlbGV0ZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9kZWxldGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQ3LTQ0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9kZWxldGUoYTogQWNjb3VudCwgYjogYnl0ZXMpOiB2b2lkIHsKICAgIHByb3RvIDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0OQogICAgLy8gb3AuQXBwTG9jYWwuZGVsZXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2RlbAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsQ29udHJhY3QudmVyaWZ5X2V4aXN0cyhhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2V4aXN0czoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NTItNDUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gdmVyaWZ5X2V4aXN0cyhhOiBBY2NvdW50LCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDU0CiAgICAvLyBjb25zdCBbX3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwTG9jYWwuZ2V0RXhVaW50NjQoYSwgMCwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgaW50Y18xIC8vIDAKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYnVyeSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDU1CiAgICAvLyByZXR1cm4gZXhpc3RzCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfcHV0X3VpbnQ2NChhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCkgLT4gdm9pZDoKdmVyaWZ5X3B1dF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDU4LTQ1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfdWludDY0KGE6IEFjY291bnQsIGI6IGJ5dGVzLCBjOiB1aW50NjQpOiB2b2lkIHsKICAgIHByb3RvIDMgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2MAogICAgLy8gb3AuQXBwTG9jYWwucHV0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC52ZXJpZnlfcHV0X2J5dGVzKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeV9wdXRfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDYzLTQ2NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHZlcmlmeV9wdXRfYnl0ZXMoYTogQWNjb3VudCwgYjogYnl0ZXMsIGM6IGJ5dGVzKTogdm9pZCB7CiAgICBwcm90byAzIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0NjUKICAgIC8vIG9wLkFwcExvY2FsLnB1dChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" }, "state": { "global": { @@ -67,11 +67,11 @@ }, "local": { "declared": { - "local_bytes": { + "localBytes": { "type": "bytes", "key": "local_bytes" }, - "local_uint64": { + "localUint64": { "type": "uint64", "key": "local_uint64" } diff --git a/tests/artifacts/state-ops/data/StateAppLocalContract.arc56.json b/tests/artifacts/state-ops/data/StateAppLocalContract.arc56.json new file mode 100644 index 0000000..2b5b6a5 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppLocalContract.arc56.json @@ -0,0 +1,338 @@ +{ + "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 index 573a8b4..fb6bff4 100644 --- a/tests/artifacts/state-ops/data/StateAppLocalContract.clear.teal +++ b/tests/artifacts/state-ops/data/StateAppLocalContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAppLocalContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:349 - // class StateAppLocalContract(ARC4Contract): - int 1 +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 index bd92746..013cc9f 100644 --- a/tests/artifacts/state-ops/data/StateAppLocalExContract.approval.teal +++ b/tests/artifacts/state-ops/data/StateAppLocalExContract.approval.teal @@ -1,77 +1,87 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAppLocalExContract.approval_program: - // tests/artifacts/StateOps/contract.py:323 - // class StateAppLocalExContract(ARC4Contract): +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 main_bare_routing@5 - method "opt_in()void" + bz __puya_arc4_router___bare_routing@5 + pushbytes 0x30c6d58a // method "opt_in()void" txna ApplicationArgs 0 - match main_opt_in_route@2 - err // reject transaction + match __puya_arc4_router___opt_in_route@2 + intc_1 // 0 + retsub -main_opt_in_route@2: - // tests/artifacts/StateOps/contract.py:340 - // @arc4.abimethod(allow_actions=["OptIn"]) +__puya_arc4_router___opt_in_route@2: + // tests/artifacts/state-ops/contract.algo.ts:405 + // @arc4.abimethod({ allowActions: ['OptIn'] }) txn OnCompletion - int OptIn + intc_0 // OptIn == - assert // OnCompletion is OptIn + assert // OnCompletion is not OptIn txn ApplicationID - assert // is not creating + assert // can only call when not creating callsub opt_in - int 1 - return + intc_0 // 1 + retsub -main_bare_routing@5: - // tests/artifacts/StateOps/contract.py:323 - // class StateAppLocalExContract(ARC4Contract): +__puya_arc4_router___bare_routing@5: + // tests/artifacts/state-ops/contract.algo.ts:400 + // export class StateAppLocalExContract extends arc4.Contract { txn OnCompletion - ! - assert // reject transaction + bnz __puya_arc4_router___after_if_else@9 txn ApplicationID ! - assert // is creating - int 1 - return + 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.StateOps.contract.StateAppLocalExContract.opt_in() -> void: +// tests/artifacts/state-ops/contract.algo.ts::StateAppLocalExContract.opt_in() -> void: opt_in: - // tests/artifacts/StateOps/contract.py:340-341 - // @arc4.abimethod(allow_actions=["OptIn"]) - // def opt_in(self) -> None: + // tests/artifacts/state-ops/contract.algo.ts:405-406 + // @arc4.abimethod({ allowActions: ['OptIn'] }) + // opt_in(): void { proto 0 0 - // tests/artifacts/StateOps/contract.py:342 - // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes_from_external_contract") + // tests/artifacts/state-ops/contract.algo.ts:407 + // this.localBytes(Global.creatorAddress).value = Bytes('dummy_bytes_from_external_contract') global CreatorAddress - // tests/artifacts/StateOps/contract.py:332 - // key="local_bytes", - byte "local_bytes" - // tests/artifacts/StateOps/contract.py:342 - // self.local_bytes[Global.creator_address] = Bytes(b"dummy_bytes_from_external_contract") - byte 0x64756d6d795f62797465735f66726f6d5f65787465726e616c5f636f6e7472616374 + // 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/StateOps/contract.py:343 - // self.local_uint64[Global.creator_address] = UInt64(99) + // tests/artifacts/state-ops/contract.algo.ts:408 + // this.localUint64(Global.creatorAddress).value = Uint64(99) global CreatorAddress - // tests/artifacts/StateOps/contract.py:327 - // key="local_uint64", - byte "local_uint64" - // tests/artifacts/StateOps/contract.py:343 - // self.local_uint64[Global.creator_address] = UInt64(99) - int 99 + // 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/StateOps/contract.py:344 - // self.local_arc4_bytes[Global.creator_address] = algopy.arc4.DynamicBytes( + // tests/artifacts/state-ops/contract.algo.ts:409 + // this.localArc4Bytes(Global.creatorAddress).value = new DynamicBytes('dummy_arc4_bytes') global CreatorAddress - // tests/artifacts/StateOps/contract.py:337 - // key="local_arc4_bytes", - byte "local_arc4_bytes" - // tests/artifacts/StateOps/contract.py:344-346 - // self.local_arc4_bytes[Global.creator_address] = algopy.arc4.DynamicBytes( - // b"dummy_arc4_bytes" - // ) - byte 0x001064756d6d795f617263345f6279746573 + // 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 index dc09a19..84e8dfe 100644 --- a/tests/artifacts/state-ops/data/StateAppLocalExContract.arc32.json +++ b/tests/artifacts/state-ops/data/StateAppLocalExContract.arc32.json @@ -7,8 +7,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjMKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdANQogICAgbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX29wdF9pbl9yb3V0ZUAyCiAgICBlcnIgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCgptYWluX29wdF9pbl9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBPcHRJbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0A1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMyMwogICAgLy8gY2xhc3MgU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3Qub3B0X2luKCkgLT4gdm9pZDoKb3B0X2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0MC0zNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiT3B0SW4iXSkKICAgIC8vIGRlZiBvcHRfaW4oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0MgogICAgLy8gc2VsZi5sb2NhbF9ieXRlc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IEJ5dGVzKGIiZHVtbXlfYnl0ZXNfZnJvbV9leHRlcm5hbF9jb250cmFjdCIpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMzIKICAgIC8vIGtleT0ibG9jYWxfYnl0ZXMiLAogICAgYnl0ZSAibG9jYWxfYnl0ZXMiCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQyCiAgICAvLyBzZWxmLmxvY2FsX2J5dGVzW0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gQnl0ZXMoYiJkdW1teV9ieXRlc19mcm9tX2V4dGVybmFsX2NvbnRyYWN0IikKICAgIGJ5dGUgMHg2NDc1NmQ2ZDc5NWY2Mjc5NzQ2NTczNWY2NjcyNmY2ZDVmNjU3ODc0NjU3MjZlNjE2YzVmNjM2ZjZlNzQ3MjYxNjM3NAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0MwogICAgLy8gc2VsZi5sb2NhbF91aW50NjRbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBVSW50NjQoOTkpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjcKICAgIC8vIGtleT0ibG9jYWxfdWludDY0IiwKICAgIGJ5dGUgImxvY2FsX3VpbnQ2NCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozNDMKICAgIC8vIHNlbGYubG9jYWxfdWludDY0W0dsb2JhbC5jcmVhdG9yX2FkZHJlc3NdID0gVUludDY0KDk5KQogICAgaW50IDk5CiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzQ0CiAgICAvLyBzZWxmLmxvY2FsX2FyYzRfYnl0ZXNbR2xvYmFsLmNyZWF0b3JfYWRkcmVzc10gPSBhbGdvcHkuYXJjNC5EeW5hbWljQnl0ZXMoCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMzcKICAgIC8vIGtleT0ibG9jYWxfYXJjNF9ieXRlcyIsCiAgICBieXRlICJsb2NhbF9hcmM0X2J5dGVzIgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjM0NC0zNDYKICAgIC8vIHNlbGYubG9jYWxfYXJjNF9ieXRlc1tHbG9iYWwuY3JlYXRvcl9hZGRyZXNzXSA9IGFsZ29weS5hcmM0LkR5bmFtaWNCeXRlcygKICAgIC8vICAgICBiImR1bW15X2FyYzRfYnl0ZXMiCiAgICAvLyApCiAgICBieXRlIDB4MDAxMDY0NzU2ZDZkNzk1ZjYxNzI2MzM0NWY2Mjc5NzQ2NTczCiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjMKICAgIC8vIGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICBpbnQgMQogICAgcmV0dXJuCg==" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxFeENvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBMb2NhbEV4Q29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwMAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANQogICAgcHVzaGJ5dGVzIDB4MzBjNmQ1OGEgLy8gbWV0aG9kICJvcHRfaW4oKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19vcHRfaW5fcm91dGVAMgogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2luX3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoeyBhbGxvd0FjdGlvbnM6IFsnT3B0SW4nXSB9KQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50Y18wIC8vIE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgT3B0SW4KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBvcHRfaW4KICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwMAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA5CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwMAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwTG9jYWxFeENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcExvY2FsRXhDb250cmFjdC5vcHRfaW4oKSAtPiB2b2lkOgpvcHRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDA1LTQwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHsgYWxsb3dBY3Rpb25zOiBbJ09wdEluJ10gfSkKICAgIC8vIG9wdF9pbigpOiB2b2lkIHsKICAgIHByb3RvIDAgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwNwogICAgLy8gdGhpcy5sb2NhbEJ5dGVzKEdsb2JhbC5jcmVhdG9yQWRkcmVzcykudmFsdWUgPSBCeXRlcygnZHVtbXlfYnl0ZXNfZnJvbV9leHRlcm5hbF9jb250cmFjdCcpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDIKICAgIC8vIGxvY2FsQnl0ZXMgPSBMb2NhbFN0YXRlPGJ5dGVzPih7IGtleTogJ2xvY2FsX2J5dGVzJyB9KQogICAgcHVzaGJ5dGVzcyAibG9jYWxfYnl0ZXMiICJkdW1teV9ieXRlc19mcm9tX2V4dGVybmFsX2NvbnRyYWN0IiAvLyAibG9jYWxfYnl0ZXMiLCAiZHVtbXlfYnl0ZXNfZnJvbV9leHRlcm5hbF9jb250cmFjdCIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDcKICAgIC8vIHRoaXMubG9jYWxCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gQnl0ZXMoJ2R1bW15X2J5dGVzX2Zyb21fZXh0ZXJuYWxfY29udHJhY3QnKQogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwOAogICAgLy8gdGhpcy5sb2NhbFVpbnQ2NChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gVWludDY0KDk5KQogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDAxCiAgICAvLyBsb2NhbFVpbnQ2NCA9IExvY2FsU3RhdGU8dWludDY0Pih7IGtleTogJ2xvY2FsX3VpbnQ2NCcgfSkKICAgIHB1c2hieXRlcyAibG9jYWxfdWludDY0IgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwOAogICAgLy8gdGhpcy5sb2NhbFVpbnQ2NChHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gVWludDY0KDk5KQogICAgcHVzaGludCA5OSAvLyA5OQogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQwOQogICAgLy8gdGhpcy5sb2NhbEFyYzRCeXRlcyhHbG9iYWwuY3JlYXRvckFkZHJlc3MpLnZhbHVlID0gbmV3IER5bmFtaWNCeXRlcygnZHVtbXlfYXJjNF9ieXRlcycpCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDMKICAgIC8vIGxvY2FsQXJjNEJ5dGVzID0gTG9jYWxTdGF0ZTxEeW5hbWljQnl0ZXM+KHsga2V5OiAnbG9jYWxfYXJjNF9ieXRlcycgfSkKICAgIHB1c2hieXRlc3MgImxvY2FsX2FyYzRfYnl0ZXMiIDB4MDAxMDY0NzU2ZDZkNzk1ZjYxNzI2MzM0NWY2Mjc5NzQ2NTczIC8vICJsb2NhbF9hcmM0X2J5dGVzIiwgMHgwMDEwNjQ3NTZkNmQ3OTVmNjE3MjYzMzQ1ZjYyNzk3NDY1NzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MDkKICAgIC8vIHRoaXMubG9jYWxBcmM0Qnl0ZXMoR2xvYmFsLmNyZWF0b3JBZGRyZXNzKS52YWx1ZSA9IG5ldyBEeW5hbWljQnl0ZXMoJ2R1bW15X2FyYzRfYnl0ZXMnKQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwTG9jYWxFeENvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" }, "state": { "global": { @@ -27,15 +27,15 @@ }, "local": { "declared": { - "local_arc4_bytes": { + "localArc4Bytes": { "type": "bytes", "key": "local_arc4_bytes" }, - "local_bytes": { + "localBytes": { "type": "bytes", "key": "local_bytes" }, - "local_uint64": { + "localUint64": { "type": "uint64", "key": "local_uint64" } diff --git a/tests/artifacts/state-ops/data/StateAppLocalExContract.arc56.json b/tests/artifacts/state-ops/data/StateAppLocalExContract.arc56.json new file mode 100644 index 0000000..81312e3 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppLocalExContract.arc56.json @@ -0,0 +1,106 @@ +{ + "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 index c4080e2..aec0884 100644 --- a/tests/artifacts/state-ops/data/StateAppLocalExContract.clear.teal +++ b/tests/artifacts/state-ops/data/StateAppLocalExContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAppLocalExContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:323 - // class StateAppLocalExContract(ARC4Contract): - int 1 +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 index d7d91f2..4f346cc 100644 --- a/tests/artifacts/state-ops/data/StateAppParamsContract.approval.teal +++ b/tests/artifacts/state-ops/data/StateAppParamsContract.approval.teal @@ -1,37 +1,39 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAppParamsContract.approval_program: - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): +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 main_bare_routing@13 - 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" + 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 main_verify_app_params_get_approval_program_route@2 main_verify_app_params_get_clear_state_program_route@3 main_verify_app_params_get_global_num_uint_route@4 main_verify_app_params_get_global_num_byte_slice_route@5 main_verify_app_params_get_local_num_uint_route@6 main_verify_app_params_get_local_num_byte_slice_route@7 main_verify_app_params_get_extra_program_pages_route@8 main_verify_app_params_get_creator_route@9 main_verify_app_params_get_address_route@10 - err // reject transaction + 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 -main_verify_app_params_get_approval_program_route@2: - // tests/artifacts/StateOps/contract.py:250 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): + 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/StateOps/contract.py:250 + // tests/artifacts/state-ops/contract.algo.ts:267 // @arc4.abimethod() callsub verify_app_params_get_approval_program dup @@ -40,27 +42,27 @@ main_verify_app_params_get_approval_program_route@2: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_app_params_get_clear_state_program_route@3: - // tests/artifacts/StateOps/contract.py:258 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): + 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/StateOps/contract.py:258 + // tests/artifacts/state-ops/contract.algo.ts:276 // @arc4.abimethod() callsub verify_app_params_get_clear_state_program dup @@ -69,479 +71,466 @@ main_verify_app_params_get_clear_state_program_route@3: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_app_params_get_global_num_uint_route@4: - // tests/artifacts/StateOps/contract.py:266 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): + 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/StateOps/contract.py:266 + // tests/artifacts/state-ops/contract.algo.ts:285 // @arc4.abimethod() callsub verify_app_params_get_global_num_uint itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_app_params_get_global_num_byte_slice_route@5: - // tests/artifacts/StateOps/contract.py:274 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): + 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/StateOps/contract.py:274 + // tests/artifacts/state-ops/contract.algo.ts:294 // @arc4.abimethod() callsub verify_app_params_get_global_num_byte_slice itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_app_params_get_local_num_uint_route@6: - // tests/artifacts/StateOps/contract.py:282 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): + 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/StateOps/contract.py:282 + // tests/artifacts/state-ops/contract.algo.ts:303 // @arc4.abimethod() callsub verify_app_params_get_local_num_uint itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_app_params_get_local_num_byte_slice_route@7: - // tests/artifacts/StateOps/contract.py:290 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): + 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/StateOps/contract.py:290 + // tests/artifacts/state-ops/contract.algo.ts:312 // @arc4.abimethod() callsub verify_app_params_get_local_num_byte_slice itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_app_params_get_extra_program_pages_route@8: - // tests/artifacts/StateOps/contract.py:298 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): + 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/StateOps/contract.py:298 + // tests/artifacts/state-ops/contract.algo.ts:321 // @arc4.abimethod() callsub verify_app_params_get_extra_program_pages itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_app_params_get_creator_route@9: - // tests/artifacts/StateOps/contract.py:306 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): + 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/StateOps/contract.py:306 + // tests/artifacts/state-ops/contract.algo.ts:330 // @arc4.abimethod() callsub verify_app_params_get_creator - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_app_params_get_address_route@10: - // tests/artifacts/StateOps/contract.py:314 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): + 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/StateOps/contract.py:314 + // tests/artifacts/state-ops/contract.algo.ts:339 // @arc4.abimethod() callsub verify_app_params_get_address - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_bare_routing@13: - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): +__puya_arc4_router___bare_routing@13: + // tests/artifacts/state-ops/contract.algo.ts:266 + // export class StateAppParamsContract extends arc4.Contract { txn OnCompletion - ! - assert // reject transaction + bnz __puya_arc4_router___after_if_else@17 txn ApplicationID ! - assert // is creating - int 1 - return + 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.StateOps.contract.StateAppParamsContract.verify_app_params_get_approval_program(a: uint64) -> bytes: + +// 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/StateOps/contract.py:250-251 + // tests/artifacts/state-ops/contract.algo.ts:267-268 // @arc4.abimethod() - // def verify_app_params_get_approval_program(self, a: Application) -> Bytes: + // public verify_app_params_get_approval_program(a: Application): bytes { proto 1 1 - // tests/artifacts/StateOps/contract.py:252 - // value, exists = op.AppParamsGet.app_approval_program(a) + // tests/artifacts/state-ops/contract.algo.ts:269 + // const [value, exists] = op.AppParams.appApprovalProgram(a) frame_dig -1 app_params_get AppApprovalProgram - swap - // tests/artifacts/StateOps/contract.py:253 - // value_index, exists_index = op.AppParamsGet.app_approval_program(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:254 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:255 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:256 + // tests/artifacts/state-ops/contract.algo.ts:273 // return value retsub -// tests.artifacts.StateOps.contract._get_1st_ref_index() -> uint64: -_get_1st_ref_index: - // tests/artifacts/StateOps/contract.py:19-20 - // @subroutine - // def _get_1st_ref_index() -> UInt64: +// 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/StateOps/contract.py:21 - // return op.btoi(Txn.application_args(1)) - txna ApplicationArgs 1 + // tests/artifacts/state-ops/contract.algo.ts:23 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs btoi retsub -// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_clear_state_program(a: uint64) -> bytes: +// 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/StateOps/contract.py:258-259 + // tests/artifacts/state-ops/contract.algo.ts:276-277 // @arc4.abimethod() - // def verify_app_params_get_clear_state_program(self, a: Application) -> Bytes: + // public verify_app_params_get_clear_state_program(a: Application): bytes { proto 1 1 - // tests/artifacts/StateOps/contract.py:260 - // value, exists = op.AppParamsGet.app_clear_state_program(a) + // tests/artifacts/state-ops/contract.algo.ts:278 + // const [value, exists] = op.AppParams.appClearStateProgram(a) frame_dig -1 app_params_get AppClearStateProgram - swap - // tests/artifacts/StateOps/contract.py:261 - // value_index, exists_index = op.AppParamsGet.app_clear_state_program(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:262 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:263 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:264 + // tests/artifacts/state-ops/contract.algo.ts:282 // return value retsub -// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_global_num_uint(a: uint64) -> uint64: +// 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/StateOps/contract.py:266-267 + // tests/artifacts/state-ops/contract.algo.ts:285-286 // @arc4.abimethod() - // def verify_app_params_get_global_num_uint(self, a: Application) -> UInt64: + // public verify_app_params_get_global_num_uint(a: Application): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:268 - // value, exists = op.AppParamsGet.app_global_num_uint(a) + // tests/artifacts/state-ops/contract.algo.ts:287 + // const [value, exists] = op.AppParams.appGlobalNumUint(a) frame_dig -1 app_params_get AppGlobalNumUint - swap - // tests/artifacts/StateOps/contract.py:269 - // value_index, exists_index = op.AppParamsGet.app_global_num_uint(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:270 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:271 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:272 + // tests/artifacts/state-ops/contract.algo.ts:291 // return value retsub -// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_global_num_byte_slice(a: uint64) -> uint64: +// 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/StateOps/contract.py:274-275 + // tests/artifacts/state-ops/contract.algo.ts:294-295 // @arc4.abimethod() - // def verify_app_params_get_global_num_byte_slice(self, a: Application) -> UInt64: + // public verify_app_params_get_global_num_byte_slice(a: Application): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:276 - // value, exists = op.AppParamsGet.app_global_num_byte_slice(a) + // tests/artifacts/state-ops/contract.algo.ts:296 + // const [value, exists] = op.AppParams.appGlobalNumByteSlice(a) frame_dig -1 app_params_get AppGlobalNumByteSlice - swap - // tests/artifacts/StateOps/contract.py:277 - // value_index, exists_index = op.AppParamsGet.app_global_num_byte_slice(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:278 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:279 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:280 + // tests/artifacts/state-ops/contract.algo.ts:300 // return value retsub -// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_local_num_uint(a: uint64) -> uint64: +// 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/StateOps/contract.py:282-283 + // tests/artifacts/state-ops/contract.algo.ts:303-304 // @arc4.abimethod() - // def verify_app_params_get_local_num_uint(self, a: Application) -> UInt64: + // public verify_app_params_get_local_num_uint(a: Application): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:284 - // value, exists = op.AppParamsGet.app_local_num_uint(a) + // tests/artifacts/state-ops/contract.algo.ts:305 + // const [value, exists] = op.AppParams.appLocalNumUint(a) frame_dig -1 app_params_get AppLocalNumUint - swap - // tests/artifacts/StateOps/contract.py:285 - // value_index, exists_index = op.AppParamsGet.app_local_num_uint(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:286 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:287 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:288 + // tests/artifacts/state-ops/contract.algo.ts:309 // return value retsub -// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_local_num_byte_slice(a: uint64) -> uint64: +// 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/StateOps/contract.py:290-291 + // tests/artifacts/state-ops/contract.algo.ts:312-313 // @arc4.abimethod() - // def verify_app_params_get_local_num_byte_slice(self, a: Application) -> UInt64: + // public verify_app_params_get_local_num_byte_slice(a: Application): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:292 - // value, exists = op.AppParamsGet.app_local_num_byte_slice(a) + // tests/artifacts/state-ops/contract.algo.ts:314 + // const [value, exists] = op.AppParams.appLocalNumByteSlice(a) frame_dig -1 app_params_get AppLocalNumByteSlice - swap - // tests/artifacts/StateOps/contract.py:293 - // value_index, exists_index = op.AppParamsGet.app_local_num_byte_slice(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:294 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:295 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:296 + // tests/artifacts/state-ops/contract.algo.ts:318 // return value retsub -// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_extra_program_pages(a: uint64) -> uint64: +// 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/StateOps/contract.py:298-299 + // tests/artifacts/state-ops/contract.algo.ts:321-322 // @arc4.abimethod() - // def verify_app_params_get_extra_program_pages(self, a: Application) -> UInt64: + // public verify_app_params_get_extra_program_pages(a: Application): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:300 - // value, exists = op.AppParamsGet.app_extra_program_pages(a) + // tests/artifacts/state-ops/contract.algo.ts:323 + // const [value, exists] = op.AppParams.appExtraProgramPages(a) frame_dig -1 app_params_get AppExtraProgramPages - swap - // tests/artifacts/StateOps/contract.py:301 - // value_index, exists_index = op.AppParamsGet.app_extra_program_pages(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:302 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:303 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:304 + // tests/artifacts/state-ops/contract.algo.ts:327 // return value retsub -// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_creator(a: uint64) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_creator(a: uint64) -> bytes: verify_app_params_get_creator: - // tests/artifacts/StateOps/contract.py:306-307 + // tests/artifacts/state-ops/contract.algo.ts:330-331 // @arc4.abimethod() - // def verify_app_params_get_creator(self, a: Application) -> arc4.Address: + // public verify_app_params_get_creator(a: Application): Address { proto 1 1 - // tests/artifacts/StateOps/contract.py:308 - // value, exists = op.AppParamsGet.app_creator(a) + // tests/artifacts/state-ops/contract.algo.ts:332 + // const [value, exists] = op.AppParams.appCreator(a) frame_dig -1 app_params_get AppCreator - swap - // tests/artifacts/StateOps/contract.py:309 - // value_index, exists_index = op.AppParamsGet.app_creator(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:310 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:311 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:312 - // return arc4.Address(value) + // tests/artifacts/state-ops/contract.algo.ts:336 + // return new Address(value) retsub -// tests.artifacts.StateOps.contract.StateAppParamsContract.verify_app_params_get_address(a: uint64) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAppParamsContract.verify_app_params_get_address(a: uint64) -> bytes: verify_app_params_get_address: - // tests/artifacts/StateOps/contract.py:314-315 + // tests/artifacts/state-ops/contract.algo.ts:339-340 // @arc4.abimethod() - // def verify_app_params_get_address(self, a: Application) -> arc4.Address: + // public verify_app_params_get_address(a: Application): Address { proto 1 1 - // tests/artifacts/StateOps/contract.py:316 - // value, exists = op.AppParamsGet.app_address(a) + // tests/artifacts/state-ops/contract.algo.ts:341 + // const [value, exists] = op.AppParams.appAddress(a) frame_dig -1 app_params_get AppAddress - swap - // tests/artifacts/StateOps/contract.py:317 - // value_index, exists_index = op.AppParamsGet.app_address(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:318 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:319 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:320 - // return arc4.Address(value) + // 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 index 76ab2a1..79db0e7 100644 --- a/tests/artifacts/state-ops/data/StateAppParamsContract.arc32.json +++ b/tests/artifacts/state-ops/data/StateAppParamsContract.arc32.json @@ -47,8 +47,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBQYXJhbXNDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDEzCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtKGFwcGxpY2F0aW9uKWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0oYXBwbGljYXRpb24pYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50KGFwcGxpY2F0aW9uKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludChhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGFwcGxpY2F0aW9uKXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXBwbGljYXRpb24pYWRkcmVzcyIKICAgIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3MoYXBwbGljYXRpb24pYWRkcmVzcyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW1fcm91dGVAMiBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtX3JvdXRlQDMgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50X3JvdXRlQDQgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDUgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnRfcm91dGVANiBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3IG1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXNfcm91dGVAOCBtYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yX3JvdXRlQDkgbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzc19yb3V0ZUAxMAogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfYXBwcm92YWxfcHJvZ3JhbV9yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW0KICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjc0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjc0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50CiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlcwogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXBwX3BhcmFtc19nZXRfY3JlYXRvcl9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDgKICAgIC8vIGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Nfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzcwogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQ4CiAgICAvLyBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW0oYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUwLTI1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYXBwcm92YWxfcHJvZ3JhbShzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNTIKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2FwcHJvdmFsX3Byb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQXBwcm92YWxQcm9ncmFtCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjUzCiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9hcHByb3ZhbF9wcm9ncmFtKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEFwcHJvdmFsUHJvZ3JhbQogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1NAogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1NQogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI1NgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuX2dldF8xc3RfcmVmX2luZGV4KCkgLT4gdWludDY0OgpfZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTktMjAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgX2dldF8xc3RfcmVmX2luZGV4KCkgLT4gVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjEKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbl9hcmdzKDEpKQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0oYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjU4LTI1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbShzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjAKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2NsZWFyX3N0YXRlX3Byb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjEKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2NsZWFyX3N0YXRlX3Byb2dyYW0oX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjIKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjMKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludChhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjYtMjY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI2OAogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfZ2xvYmFsX251bV91aW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEdsb2JhbE51bVVpbnQKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNjkKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2dsb2JhbF9udW1fdWludChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1VaW50CiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjcwCiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjcxCiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjcyCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2UoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjc0LTI3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlKHNlbGYsIGE6IEFwcGxpY2F0aW9uKSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzYKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2dsb2JhbF9udW1fYnl0ZV9zbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1CeXRlU2xpY2UKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzcKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2dsb2JhbF9udW1fYnl0ZV9zbGljZShfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1CeXRlU2xpY2UKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzgKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNzkKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODAKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjgyLTI4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI4NAogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfbG9jYWxfbnVtX3VpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwTG9jYWxOdW1VaW50CiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjg1CiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9sb2NhbF9udW1fdWludChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBMb2NhbE51bVVpbnQKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODYKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODcKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyODgKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjkwLTI5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2Uoc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI5MgogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfbG9jYWxfbnVtX2J5dGVfc2xpY2UoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwTG9jYWxOdW1CeXRlU2xpY2UKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTMKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2xvY2FsX251bV9ieXRlX3NsaWNlKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcExvY2FsTnVtQnl0ZVNsaWNlCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk0CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk1CiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6Mjk2CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyOTgtMjk5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKHNlbGYsIGE6IEFwcGxpY2F0aW9uKSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDAKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2V4dHJhX3Byb2dyYW1fcGFnZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDEKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2V4dHJhX3Byb2dyYW1fcGFnZXMoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDIKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDMKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzA2LTMwNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY3JlYXRvcihzZWxmLCBhOiBBcHBsaWNhdGlvbikgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzA4CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9jcmVhdG9yKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcENyZWF0b3IKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMDkKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5BcHBQYXJhbXNHZXQuYXBwX2NyZWF0b3IoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwQ3JlYXRvcgogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxMAogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxMQogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxMgogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxNC0zMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Moc2VsZiwgYTogQXBwbGljYXRpb24pIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjMxNgogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFwcFBhcmFtc0dldC5hcHBfYWRkcmVzcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBBZGRyZXNzCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MzE3CiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXBwUGFyYW1zR2V0LmFwcF9hZGRyZXNzKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEFkZHJlc3MKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTgKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMTkKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weTozMjAKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBcHBQYXJhbXNDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDEgMAogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMwogICAgcHVzaGJ5dGVzcyAweDVlN2I3ZDUyIDB4ZTI5ZTMwZWUgMHg1ODgxOTA5OSAweGNhNzdiNTliIDB4NTNjMGRkOWIgMHg1ZjAwMDcwMyAweGQ3N2JkMjFmIDB4YTk0MWE3NDYgMHhiZDNlOWVlYyAvLyBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtKGFwcGxpY2F0aW9uKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW0oYXBwbGljYXRpb24pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50KGFwcGxpY2F0aW9uKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludChhcHBsaWNhdGlvbil1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhcHBsaWNhdGlvbil1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzKGFwcGxpY2F0aW9uKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXBwbGljYXRpb24pYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3MoYXBwbGljYXRpb24pYWRkcmVzcyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW1fcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50X3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fdWludF9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzc19yb3V0ZUAxMAogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW1fcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NsZWFyX3N0YXRlX3Byb2dyYW1fcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2dsb2JhbF9udW1fYnl0ZV9zbGljZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50X3JvdXRlQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXBwX3BhcmFtc19nZXRfZXh0cmFfcHJvZ3JhbV9wYWdlc19yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFwcGxpY2F0aW9ucwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY3JlYXRvcgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FkZHJlc3Nfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBcHBQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXBwUGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE3CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2Ny0yNjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2FwcHJvdmFsX3Byb2dyYW0oYTogQXBwbGljYXRpb24pOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjkKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFwcFBhcmFtcy5hcHBBcHByb3ZhbFByb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQXBwcm92YWxQcm9ncmFtCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5BcHBQYXJhbXMuYXBwQXBwcm92YWxQcm9ncmFtKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBBcHByb3ZhbFByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcyCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzYtMjc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9jbGVhcl9zdGF0ZV9wcm9ncmFtKGE6IEFwcGxpY2F0aW9uKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc4CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5BcHBQYXJhbXMuYXBwQ2xlYXJTdGF0ZVByb2dyYW0oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzkKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBDbGVhclN0YXRlUHJvZ3JhbShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyODAKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjgxCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyODIKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg1LTI4NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV91aW50KGE6IEFwcGxpY2F0aW9uKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NwogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwUGFyYW1zLmFwcEdsb2JhbE51bVVpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwR2xvYmFsTnVtVWludAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcEdsb2JhbE51bVVpbnQoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEdsb2JhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyODkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkwCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2UoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9nbG9iYWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk0LTI5NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfZ2xvYmFsX251bV9ieXRlX3NsaWNlKGE6IEFwcGxpY2F0aW9uKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5NgogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwUGFyYW1zLmFwcEdsb2JhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBHbG9iYWxOdW1CeXRlU2xpY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTcKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBHbG9iYWxOdW1CeXRlU2xpY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEdsb2JhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5OAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTkKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2xvY2FsX251bV91aW50KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAzLTMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX3VpbnQoYTogQXBwbGljYXRpb24pOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA1CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5BcHBQYXJhbXMuYXBwTG9jYWxOdW1VaW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcExvY2FsTnVtVWludAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNgogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcExvY2FsTnVtVWludChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwTG9jYWxOdW1VaW50CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA3CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA5CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfbG9jYWxfbnVtX2J5dGVfc2xpY2UoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMTItMzEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9sb2NhbF9udW1fYnl0ZV9zbGljZShhOiBBcHBsaWNhdGlvbik6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMTQKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFwcFBhcmFtcy5hcHBMb2NhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfcGFyYW1zX2dldCBBcHBMb2NhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcExvY2FsTnVtQnl0ZVNsaWNlKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBMb2NhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNgogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMTcKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxOAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QudmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXMoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9leHRyYV9wcm9ncmFtX3BhZ2VzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMS0zMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2V4dHJhX3Byb2dyYW1fcGFnZXMoYTogQXBwbGljYXRpb24pOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIzCiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5BcHBQYXJhbXMuYXBwRXh0cmFQcm9ncmFtUGFnZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMjQKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBFeHRyYVByb2dyYW1QYWdlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXBwX3BhcmFtc19nZXQgQXBwRXh0cmFQcm9ncmFtUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMjUKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzI2CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFwcFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hcHBfcGFyYW1zX2dldF9jcmVhdG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMC0zMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FwcF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogQXBwbGljYXRpb24pOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMgogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXBwUGFyYW1zLmFwcENyZWF0b3IoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX3BhcmFtc19nZXQgQXBwQ3JlYXRvcgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMwogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXBwUGFyYW1zLmFwcENyZWF0b3IoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcENyZWF0b3IKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMzQKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMzYKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBcHBQYXJhbXNDb250cmFjdC52ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzcyhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXBwX3BhcmFtc19nZXRfYWRkcmVzczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMzktMzQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hcHBfcGFyYW1zX2dldF9hZGRyZXNzKGE6IEFwcGxpY2F0aW9uKTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFwcFBhcmFtcy5hcHBBZGRyZXNzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9wYXJhbXNfZ2V0IEFwcEFkZHJlc3MKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDIKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFwcFBhcmFtcy5hcHBBZGRyZXNzKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhcHBfcGFyYW1zX2dldCBBcHBBZGRyZXNzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQzCiAgICAvLyBhc3NlcnQodmFsdWUuYnl0ZXMudG9TdHJpbmcoKSA9PT0gdmFsdWVfaW5kZXguYnl0ZXMudG9TdHJpbmcoKSwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNDQKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM0NQogICAgLy8gcmV0dXJuIG5ldyBBZGRyZXNzKHZhbHVlKQogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXBwUGFyYW1zQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" }, "state": { "global": { diff --git a/tests/artifacts/state-ops/data/StateAppParamsContract.arc56.json b/tests/artifacts/state-ops/data/StateAppParamsContract.arc56.json new file mode 100644 index 0000000..83355d7 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAppParamsContract.arc56.json @@ -0,0 +1,307 @@ +{ + "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 index d499707..99ff46e 100644 --- a/tests/artifacts/state-ops/data/StateAppParamsContract.clear.teal +++ b/tests/artifacts/state-ops/data/StateAppParamsContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAppParamsContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:248 - // class StateAppParamsContract(ARC4Contract): - int 1 +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 index 6b077bd..a214d29 100644 --- a/tests/artifacts/state-ops/data/StateAssetHoldingContract.approval.teal +++ b/tests/artifacts/state-ops/data/StateAssetHoldingContract.approval.teal @@ -1,115 +1,129 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAssetHoldingContract.approval_program: - // tests/artifacts/StateOps/contract.py:138 - // class StateAssetHoldingContract(ARC4Contract): +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 main_bare_routing@6 - method "verify_asset_holding_get(account,asset)uint64" - method "verify_asset_frozen_get(account,asset)bool" + 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 main_verify_asset_holding_get_route@2 main_verify_asset_frozen_get_route@3 - err // reject transaction + match __puya_arc4_router___verify_asset_holding_get_route@2 __puya_arc4_router___verify_asset_frozen_get_route@3 + intc_0 // 0 + retsub -main_verify_asset_holding_get_route@2: - // tests/artifacts/StateOps/contract.py:139 +__puya_arc4_router___verify_asset_holding_get_route@2: + // tests/artifacts/state-ops/contract.algo.ts:143 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:138 - // class StateAssetHoldingContract(ARC4Contract): + 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/StateOps/contract.py:139 + // tests/artifacts/state-ops/contract.algo.ts:143 // @arc4.abimethod() callsub verify_asset_holding_get itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_verify_asset_frozen_get_route@3: - // tests/artifacts/StateOps/contract.py:144 +__puya_arc4_router___verify_asset_frozen_get_route@3: + // tests/artifacts/state-ops/contract.algo.ts:149 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:138 - // class StateAssetHoldingContract(ARC4Contract): + 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/StateOps/contract.py:144 + // tests/artifacts/state-ops/contract.algo.ts:149 // @arc4.abimethod() callsub verify_asset_frozen_get - byte 0x00 - int 0 + pushbytes 0x00 + intc_0 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_1 // 1 + retsub -main_bare_routing@6: - // tests/artifacts/StateOps/contract.py:138 - // class StateAssetHoldingContract(ARC4Contract): +__puya_arc4_router___bare_routing@6: + // tests/artifacts/state-ops/contract.algo.ts:142 + // export class StateAssetHoldingContract extends arc4.Contract { txn OnCompletion - ! - assert // reject transaction + bnz __puya_arc4_router___after_if_else@10 txn ApplicationID ! - assert // is creating - int 1 - return + 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.StateOps.contract.StateAssetHoldingContract.verify_asset_holding_get(a: bytes, b: uint64) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetHoldingContract.verify_asset_holding_get(a: bytes, b: uint64) -> uint64: verify_asset_holding_get: - // tests/artifacts/StateOps/contract.py:139-140 + // tests/artifacts/state-ops/contract.algo.ts:143-144 // @arc4.abimethod() - // def verify_asset_holding_get(self, a: Account, b: Asset) -> UInt64: + // public verify_asset_holding_get(a: Account, b: Asset): uint64 { proto 2 1 - // tests/artifacts/StateOps/contract.py:141 - // balance, _val = op.AssetHoldingGet.asset_balance(a, b) + // 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/StateOps/contract.py:142 + // tests/artifacts/state-ops/contract.algo.ts:146 // return balance retsub -// tests.artifacts.StateOps.contract.StateAssetHoldingContract.verify_asset_frozen_get(a: bytes, b: uint64) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetHoldingContract.verify_asset_frozen_get(a: bytes, b: uint64) -> uint64: verify_asset_frozen_get: - // tests/artifacts/StateOps/contract.py:144-145 + // tests/artifacts/state-ops/contract.algo.ts:149-150 // @arc4.abimethod() - // def verify_asset_frozen_get(self, a: Account, b: Asset) -> bool: + // public verify_asset_frozen_get(a: Account, b: Asset): boolean { proto 2 1 - // tests/artifacts/StateOps/contract.py:146 - // frozen, _val = op.AssetHoldingGet.asset_frozen(a, b) + // 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/StateOps/contract.py:147 + // 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 index a7b0497..2eee37c 100644 --- a/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc32.json +++ b/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc32.json @@ -12,8 +12,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzOAogICAgLy8gY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IG1haW5fYmFyZV9yb3V0aW5nQDYKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0KGFjY291bnQsYXNzZXQpdWludDY0IgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfZnJvemVuX2dldChhY2NvdW50LGFzc2V0KWJvb2wiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX3ZlcmlmeV9hc3NldF9ob2xkaW5nX2dldF9yb3V0ZUAyIG1haW5fdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXRfcm91dGVAMwogICAgZXJyIC8vIHJlamVjdCB0cmFuc2FjdGlvbgoKbWFpbl92ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXRfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM4CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXRfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM4CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfZnJvemVuX2dldAogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTM4CiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gcmVqZWN0IHRyYW5zYWN0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0dXJuCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0KGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzOS0xNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0KHNlbGYsIGE6IEFjY291bnQsIGI6IEFzc2V0KSAtPiBVSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDEKICAgIC8vIGJhbGFuY2UsIF92YWwgPSBvcC5Bc3NldEhvbGRpbmdHZXQuYXNzZXRfYmFsYW5jZShhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQogICAgcG9wCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQyCiAgICAvLyByZXR1cm4gYmFsYW5jZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfZnJvemVuX2dldDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNDQtMTQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0KHNlbGYsIGE6IEFjY291bnQsIGI6IEFzc2V0KSAtPiBib29sOgogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTQ2CiAgICAvLyBmcm96ZW4sIF92YWwgPSBvcC5Bc3NldEhvbGRpbmdHZXQuYXNzZXRfZnJvemVuKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRGcm96ZW4KICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE0NwogICAgLy8gcmV0dXJuIGZyb3plbgogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjEzOAogICAgLy8gY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgaW50IDEKICAgIHJldHVybgo=" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QuYXBwcm92YWxQcm9ncmFtOgogICAgaW50Y2Jsb2NrIDAgMQogICAgYnl0ZWNibG9jayAweDE1MWY3Yzc1CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2CiAgICBwdXNoYnl0ZXNzIDB4NjgzMDE0NzYgMHg3ODRjNjRlYiAvLyBtZXRob2QgInZlcmlmeV9hc3NldF9ob2xkaW5nX2dldChhY2NvdW50LGFzc2V0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoYWNjb3VudCxhc3NldClib29sIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0X3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXRfcm91dGVAMwogICAgaW50Y18wIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0X3JvdXRlQDI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQyCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X2hvbGRpbmdfZ2V0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfZnJvemVuX2dldF9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0CiAgICBwdXNoYnl0ZXMgMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDIKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0SG9sZGluZ0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMSAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQyCiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldEhvbGRpbmdDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18wIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldEhvbGRpbmdDb250cmFjdC52ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQzLTE0NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfaG9sZGluZ19nZXQoYTogQWNjb3VudCwgYjogQXNzZXQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ1CiAgICAvLyBjb25zdCBbYmFsYW5jZSwgX3ZhbF0gPSBvcC5Bc3NldEhvbGRpbmcuYXNzZXRCYWxhbmNlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRCYWxhbmNlCiAgICBwb3AKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIHJldHVybiBiYWxhbmNlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QudmVyaWZ5X2Fzc2V0X2Zyb3plbl9nZXQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfZnJvemVuX2dldDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDktMTUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9mcm96ZW5fZ2V0KGE6IEFjY291bnQsIGI6IEFzc2V0KTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTEKICAgIC8vIGNvbnN0IFtmcm96ZW4sIF92YWxdID0gb3AuQXNzZXRIb2xkaW5nLmFzc2V0RnJvemVuKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRGcm96ZW4KICAgIHBvcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MgogICAgLy8gcmV0dXJuIGZyb3plbgogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRIb2xkaW5nQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW06CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" }, "state": { "global": { diff --git a/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc56.json b/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc56.json new file mode 100644 index 0000000..6aff1c8 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAssetHoldingContract.arc56.json @@ -0,0 +1,126 @@ +{ + "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 index ec6efc8..7168de9 100644 --- a/tests/artifacts/state-ops/data/StateAssetHoldingContract.clear.teal +++ b/tests/artifacts/state-ops/data/StateAssetHoldingContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAssetHoldingContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:138 - // class StateAssetHoldingContract(ARC4Contract): - int 1 +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 index b0cda94..1bbcffd 100644 --- a/tests/artifacts/state-ops/data/StateAssetParamsContract.approval.teal +++ b/tests/artifacts/state-ops/data/StateAssetParamsContract.approval.teal @@ -1,115 +1,114 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAssetParamsContract.approval_program: - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): +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 main_bare_routing@16 - 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" + 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 main_verify_asset_params_get_total_route@2 main_verify_asset_params_get_decimals_route@3 main_verify_asset_params_get_default_frozen_route@4 main_verify_asset_params_get_unit_name_route@5 main_verify_asset_params_get_name_route@6 main_verify_asset_params_get_url_route@7 main_verify_asset_params_get_metadata_hash_route@8 main_verify_asset_params_get_manager_route@9 main_verify_asset_params_get_reserve_route@10 main_verify_asset_params_get_freeze_route@11 main_verify_asset_params_get_clawback_route@12 main_verify_asset_params_get_creator_route@13 - err // reject transaction + 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 -main_verify_asset_params_get_total_route@2: - // tests/artifacts/StateOps/contract.py:151 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:151 + // tests/artifacts/state-ops/contract.algo.ts:157 // @arc4.abimethod() callsub verify_asset_params_get_total itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_decimals_route@3: - // tests/artifacts/StateOps/contract.py:159 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:159 + // tests/artifacts/state-ops/contract.algo.ts:166 // @arc4.abimethod() callsub verify_asset_params_get_decimals itob - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_default_frozen_route@4: - // tests/artifacts/StateOps/contract.py:167 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:167 + // tests/artifacts/state-ops/contract.algo.ts:175 // @arc4.abimethod() callsub verify_asset_params_get_default_frozen - byte 0x00 - int 0 + pushbytes 0x00 + intc_1 // 0 uncover 2 setbit - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_unit_name_route@5: - // tests/artifacts/StateOps/contract.py:175 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:175 + // tests/artifacts/state-ops/contract.algo.ts:184 // @arc4.abimethod() callsub verify_asset_params_get_unit_name dup @@ -118,27 +117,27 @@ main_verify_asset_params_get_unit_name_route@5: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_name_route@6: - // tests/artifacts/StateOps/contract.py:183 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:183 + // tests/artifacts/state-ops/contract.algo.ts:193 // @arc4.abimethod() callsub verify_asset_params_get_name dup @@ -147,27 +146,27 @@ main_verify_asset_params_get_name_route@6: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_url_route@7: - // tests/artifacts/StateOps/contract.py:191 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:191 + // tests/artifacts/state-ops/contract.algo.ts:202 // @arc4.abimethod() callsub verify_asset_params_get_url dup @@ -176,27 +175,27 @@ main_verify_asset_params_get_url_route@7: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_metadata_hash_route@8: - // tests/artifacts/StateOps/contract.py:199 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:199 + // tests/artifacts/state-ops/contract.algo.ts:211 // @arc4.abimethod() callsub verify_asset_params_get_metadata_hash dup @@ -205,521 +204,502 @@ main_verify_asset_params_get_metadata_hash_route@8: extract 6 2 swap concat - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_manager_route@9: - // tests/artifacts/StateOps/contract.py:207 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:207 + // tests/artifacts/state-ops/contract.algo.ts:220 // @arc4.abimethod() callsub verify_asset_params_get_manager - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_reserve_route@10: - // tests/artifacts/StateOps/contract.py:215 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:215 + // tests/artifacts/state-ops/contract.algo.ts:229 // @arc4.abimethod() callsub verify_asset_params_get_reserve - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_freeze_route@11: - // tests/artifacts/StateOps/contract.py:223 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:223 + // tests/artifacts/state-ops/contract.algo.ts:238 // @arc4.abimethod() callsub verify_asset_params_get_freeze - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_clawback_route@12: - // tests/artifacts/StateOps/contract.py:231 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:231 + // tests/artifacts/state-ops/contract.algo.ts:247 // @arc4.abimethod() callsub verify_asset_params_get_clawback - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_verify_asset_params_get_creator_route@13: - // tests/artifacts/StateOps/contract.py:239 +__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 NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): + 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/StateOps/contract.py:239 + // tests/artifacts/state-ops/contract.algo.ts:256 // @arc4.abimethod() callsub verify_asset_params_get_creator - byte 0x151f7c75 + bytec_0 // 0x151f7c75 swap concat log - int 1 - return + intc_0 // 1 + retsub -main_bare_routing@16: - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): +__puya_arc4_router___bare_routing@16: + // tests/artifacts/state-ops/contract.algo.ts:156 + // export class StateAssetParamsContract extends arc4.Contract { txn OnCompletion - ! - assert // reject transaction + bnz __puya_arc4_router___after_if_else@20 txn ApplicationID ! - assert // is creating - int 1 - return + 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.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_total(a: uint64) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_total(a: uint64) -> uint64: verify_asset_params_get_total: - // tests/artifacts/StateOps/contract.py:151-152 + // tests/artifacts/state-ops/contract.algo.ts:157-158 // @arc4.abimethod() - // def verify_asset_params_get_total(self, a: Asset) -> UInt64: + // public verify_asset_params_get_total(a: Asset): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:153 - // value, exists = op.AssetParamsGet.asset_total(a) + // tests/artifacts/state-ops/contract.algo.ts:159 + // const [value, exists] = op.AssetParams.assetTotal(a) frame_dig -1 asset_params_get AssetTotal - swap - // tests/artifacts/StateOps/contract.py:154 - // value_index, exists_index = op.AssetParamsGet.asset_total(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:155 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:156 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:157 + // tests/artifacts/state-ops/contract.algo.ts:163 // return value retsub -// tests.artifacts.StateOps.contract._get_1st_ref_index() -> uint64: -_get_1st_ref_index: - // tests/artifacts/StateOps/contract.py:19-20 - // @subroutine - // def _get_1st_ref_index() -> UInt64: +// 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/StateOps/contract.py:21 - // return op.btoi(Txn.application_args(1)) - txna ApplicationArgs 1 + // tests/artifacts/state-ops/contract.algo.ts:23 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs btoi retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_decimals(a: uint64) -> uint64: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_decimals(a: uint64) -> uint64: verify_asset_params_get_decimals: - // tests/artifacts/StateOps/contract.py:159-160 + // tests/artifacts/state-ops/contract.algo.ts:166-167 // @arc4.abimethod() - // def verify_asset_params_get_decimals(self, a: Asset) -> UInt64: + // public verify_asset_params_get_decimals(a: Asset): uint64 { proto 1 1 - // tests/artifacts/StateOps/contract.py:161 - // value, exists = op.AssetParamsGet.asset_decimals(a) + // tests/artifacts/state-ops/contract.algo.ts:168 + // const [value, exists] = op.AssetParams.assetDecimals(a) frame_dig -1 asset_params_get AssetDecimals - swap - // tests/artifacts/StateOps/contract.py:162 - // value_index, exists_index = op.AssetParamsGet.asset_decimals(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:163 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:164 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:165 + // tests/artifacts/state-ops/contract.algo.ts:172 // return value retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_default_frozen(a: uint64) -> uint64: +// 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/StateOps/contract.py:167-168 + // tests/artifacts/state-ops/contract.algo.ts:175-176 // @arc4.abimethod() - // def verify_asset_params_get_default_frozen(self, a: Asset) -> bool: + // public verify_asset_params_get_default_frozen(a: Asset): boolean { proto 1 1 - // tests/artifacts/StateOps/contract.py:169 - // value, exists = op.AssetParamsGet.asset_default_frozen(a) + // tests/artifacts/state-ops/contract.algo.ts:177 + // const [value, exists] = op.AssetParams.assetDefaultFrozen(a) frame_dig -1 asset_params_get AssetDefaultFrozen - swap - // tests/artifacts/StateOps/contract.py:170 - // value_index, exists_index = op.AssetParamsGet.asset_default_frozen(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:171 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:172 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:173 + // tests/artifacts/state-ops/contract.algo.ts:181 // return value retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_unit_name(a: uint64) -> bytes: +// 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/StateOps/contract.py:175-176 + // tests/artifacts/state-ops/contract.algo.ts:184-185 // @arc4.abimethod() - // def verify_asset_params_get_unit_name(self, a: Asset) -> Bytes: + // public verify_asset_params_get_unit_name(a: Asset): bytes { proto 1 1 - // tests/artifacts/StateOps/contract.py:177 - // value, exists = op.AssetParamsGet.asset_unit_name(a) + // tests/artifacts/state-ops/contract.algo.ts:186 + // const [value, exists] = op.AssetParams.assetUnitName(a) frame_dig -1 asset_params_get AssetUnitName - swap - // tests/artifacts/StateOps/contract.py:178 - // value_index, exists_index = op.AssetParamsGet.asset_unit_name(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:179 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:180 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:181 + // tests/artifacts/state-ops/contract.algo.ts:190 // return value retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_name(a: uint64) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_name(a: uint64) -> bytes: verify_asset_params_get_name: - // tests/artifacts/StateOps/contract.py:183-184 + // tests/artifacts/state-ops/contract.algo.ts:193-194 // @arc4.abimethod() - // def verify_asset_params_get_name(self, a: Asset) -> Bytes: + // public verify_asset_params_get_name(a: Asset): bytes { proto 1 1 - // tests/artifacts/StateOps/contract.py:185 - // value, exists = op.AssetParamsGet.asset_name(a) + // tests/artifacts/state-ops/contract.algo.ts:195 + // const [value, exists] = op.AssetParams.assetName(a) frame_dig -1 asset_params_get AssetName - swap - // tests/artifacts/StateOps/contract.py:186 - // value_index, exists_index = op.AssetParamsGet.asset_name(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:187 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:188 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:189 + // tests/artifacts/state-ops/contract.algo.ts:199 // return value retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_url(a: uint64) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_url(a: uint64) -> bytes: verify_asset_params_get_url: - // tests/artifacts/StateOps/contract.py:191-192 + // tests/artifacts/state-ops/contract.algo.ts:202-203 // @arc4.abimethod() - // def verify_asset_params_get_url(self, a: Asset) -> Bytes: + // public verify_asset_params_get_url(a: Asset): bytes { proto 1 1 - // tests/artifacts/StateOps/contract.py:193 - // value, exists = op.AssetParamsGet.asset_url(a) + // tests/artifacts/state-ops/contract.algo.ts:204 + // const [value, exists] = op.AssetParams.assetUrl(a) frame_dig -1 asset_params_get AssetURL - swap - // tests/artifacts/StateOps/contract.py:194 - // value_index, exists_index = op.AssetParamsGet.asset_url(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:195 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:196 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:197 + // tests/artifacts/state-ops/contract.algo.ts:208 // return value retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_metadata_hash(a: uint64) -> bytes: +// 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/StateOps/contract.py:199-200 + // tests/artifacts/state-ops/contract.algo.ts:211-212 // @arc4.abimethod() - // def verify_asset_params_get_metadata_hash(self, a: Asset) -> Bytes: + // public verify_asset_params_get_metadata_hash(a: Asset): bytes { proto 1 1 - // tests/artifacts/StateOps/contract.py:201 - // value, exists = op.AssetParamsGet.asset_metadata_hash(a) + // tests/artifacts/state-ops/contract.algo.ts:213 + // const [value, exists] = op.AssetParams.assetMetadataHash(a) frame_dig -1 asset_params_get AssetMetadataHash - swap - // tests/artifacts/StateOps/contract.py:202 - // value_index, exists_index = op.AssetParamsGet.asset_metadata_hash(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:203 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:204 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:205 + // tests/artifacts/state-ops/contract.algo.ts:217 // return value retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_manager(a: uint64) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_manager(a: uint64) -> bytes: verify_asset_params_get_manager: - // tests/artifacts/StateOps/contract.py:207-208 + // tests/artifacts/state-ops/contract.algo.ts:220-221 // @arc4.abimethod() - // def verify_asset_params_get_manager(self, a: Asset) -> arc4.Address: + // public verify_asset_params_get_manager(a: Asset): Address { proto 1 1 - // tests/artifacts/StateOps/contract.py:209 - // value, exists = op.AssetParamsGet.asset_manager(a) + // tests/artifacts/state-ops/contract.algo.ts:222 + // const [value, exists] = op.AssetParams.assetManager(a) frame_dig -1 asset_params_get AssetManager - swap - // tests/artifacts/StateOps/contract.py:210 - // value_index, exists_index = op.AssetParamsGet.asset_manager(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:211 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:212 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:213 - // return arc4.Address(value) + // tests/artifacts/state-ops/contract.algo.ts:226 + // return new Address(value) retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_reserve(a: uint64) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_reserve(a: uint64) -> bytes: verify_asset_params_get_reserve: - // tests/artifacts/StateOps/contract.py:215-216 + // tests/artifacts/state-ops/contract.algo.ts:229-230 // @arc4.abimethod() - // def verify_asset_params_get_reserve(self, a: Asset) -> arc4.Address: + // public verify_asset_params_get_reserve(a: Asset): Address { proto 1 1 - // tests/artifacts/StateOps/contract.py:217 - // value, exists = op.AssetParamsGet.asset_reserve(a) + // tests/artifacts/state-ops/contract.algo.ts:231 + // const [value, exists] = op.AssetParams.assetReserve(a) frame_dig -1 asset_params_get AssetReserve - swap - // tests/artifacts/StateOps/contract.py:218 - // value_index, exists_index = op.AssetParamsGet.asset_reserve(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:219 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:220 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:221 - // return arc4.Address(value) + // tests/artifacts/state-ops/contract.algo.ts:235 + // return new Address(value) retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_freeze(a: uint64) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_freeze(a: uint64) -> bytes: verify_asset_params_get_freeze: - // tests/artifacts/StateOps/contract.py:223-224 + // tests/artifacts/state-ops/contract.algo.ts:238-239 // @arc4.abimethod() - // def verify_asset_params_get_freeze(self, a: Asset) -> arc4.Address: + // public verify_asset_params_get_freeze(a: Asset): Address { proto 1 1 - // tests/artifacts/StateOps/contract.py:225 - // value, exists = op.AssetParamsGet.asset_freeze(a) + // tests/artifacts/state-ops/contract.algo.ts:240 + // const [value, exists] = op.AssetParams.assetFreeze(a) frame_dig -1 asset_params_get AssetFreeze - swap - // tests/artifacts/StateOps/contract.py:226 - // value_index, exists_index = op.AssetParamsGet.asset_freeze(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:227 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:228 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:229 - // return arc4.Address(value) + // tests/artifacts/state-ops/contract.algo.ts:244 + // return new Address(value) retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_clawback(a: uint64) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_clawback(a: uint64) -> bytes: verify_asset_params_get_clawback: - // tests/artifacts/StateOps/contract.py:231-232 + // tests/artifacts/state-ops/contract.algo.ts:247-248 // @arc4.abimethod() - // def verify_asset_params_get_clawback(self, a: Asset) -> arc4.Address: + // public verify_asset_params_get_clawback(a: Asset): Address { proto 1 1 - // tests/artifacts/StateOps/contract.py:233 - // value, exists = op.AssetParamsGet.asset_clawback(a) + // tests/artifacts/state-ops/contract.algo.ts:249 + // const [value, exists] = op.AssetParams.assetClawback(a) frame_dig -1 asset_params_get AssetClawback - swap - // tests/artifacts/StateOps/contract.py:234 - // value_index, exists_index = op.AssetParamsGet.asset_clawback(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:235 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:236 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:237 - // return arc4.Address(value) + // tests/artifacts/state-ops/contract.algo.ts:253 + // return new Address(value) retsub -// tests.artifacts.StateOps.contract.StateAssetParamsContract.verify_asset_params_get_creator(a: uint64) -> bytes: +// tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.verify_asset_params_get_creator(a: uint64) -> bytes: verify_asset_params_get_creator: - // tests/artifacts/StateOps/contract.py:239-240 + // tests/artifacts/state-ops/contract.algo.ts:256-257 // @arc4.abimethod() - // def verify_asset_params_get_creator(self, a: Asset) -> arc4.Address: + // public verify_asset_params_get_creator(a: Asset): Address { proto 1 1 - // tests/artifacts/StateOps/contract.py:241 - // value, exists = op.AssetParamsGet.asset_creator(a) + // tests/artifacts/state-ops/contract.algo.ts:258 + // const [value, exists] = op.AssetParams.assetCreator(a) frame_dig -1 asset_params_get AssetCreator - swap - // tests/artifacts/StateOps/contract.py:242 - // value_index, exists_index = op.AssetParamsGet.asset_creator(_get_1st_ref_index()) - callsub _get_1st_ref_index + // 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 - cover 2 - // tests/artifacts/StateOps/contract.py:243 - // assert value == value_index, "expected value by index to match" - dig 1 + // 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/StateOps/contract.py:244 - // assert exists == exists_index, "expected exists by index to match" - cover 2 + // 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/StateOps/contract.py:245 - // return arc4.Address(value) + // 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 index 04e164b..0d0d9d2 100644 --- a/tests/artifacts/state-ops/data/StateAssetParamsContract.arc32.json +++ b/tests/artifacts/state-ops/data/StateAssetParamsContract.arc32.json @@ -62,8 +62,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0AxNgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbChhc3NldCl1aW50NjQiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGFzc2V0KXVpbnQ2NCIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW4oYXNzZXQpYm9vbCIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lKGFzc2V0KWJ5dGVbXSIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZShhc3NldClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybChhc3NldClieXRlW10iCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2goYXNzZXQpYnl0ZVtdIgogICAgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyKGFzc2V0KWFkZHJlc3MiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYXNzZXQpYWRkcmVzcyIKICAgIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplKGFzc2V0KWFkZHJlc3MiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrKGFzc2V0KWFkZHJlc3MiCiAgICBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYXNzZXQpYWRkcmVzcyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMiBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzX3JvdXRlQDMgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbl9yb3V0ZUA0IG1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDUgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lX3JvdXRlQDYgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91cmxfcm91dGVANyBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2hfcm91dGVAOCBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXJfcm91dGVAOSBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmVfcm91dGVAMTAgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemVfcm91dGVAMTEgbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxMiBtYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAMTMKICAgIGVyciAvLyByZWplY3QgdHJhbnNhY3Rpb24KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWwKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHNfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW5fcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW4KICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZV9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTAKICAgIC8vIGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWVfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsX3JvdXRlQDc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTkxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MAogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaF9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTAKICAgIC8vIGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MAogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemVfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1MAogICAgLy8gY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2sKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcl9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHVybgoKbWFpbl9iYXJlX3JvdXRpbmdAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyByZWplY3QgdHJhbnNhY3Rpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXR1cm4KCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTEtMTUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKHNlbGYsIGE6IEFzc2V0KSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTMKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF90b3RhbChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VG90YWwKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTQKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF90b3RhbChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VG90YWwKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTUKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTYKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNTcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0Ll9nZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKX2dldF8xc3RfcmVmX2luZGV4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5LTIwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9nZXRfMXN0X3JlZl9pbmRleCgpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDAgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxCiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25fYXJncygxKSkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMoYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE1OS0xNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMoc2VsZiwgYTogQXNzZXQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2MQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2RlY2ltYWxzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXREZWNpbWFscwogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2MgogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2RlY2ltYWxzKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXREZWNpbWFscwogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2MwogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2NAogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE2NQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNjctMTY4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuKHNlbGYsIGE6IEFzc2V0KSAtPiBib29sOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTY5CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfZGVmYXVsdF9mcm96ZW4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlZmF1bHRGcm96ZW4KICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzAKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9kZWZhdWx0X2Zyb3plbihfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RGVmYXVsdEZyb3plbgogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3MQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3MgogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3MwogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc1LTE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUoc2VsZiwgYTogQXNzZXQpIC0+IEJ5dGVzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTc3CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfdW5pdF9uYW1lKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRVbml0TmFtZQogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE3OAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3VuaXRfbmFtZShfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VW5pdE5hbWUKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxNzkKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODAKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTgzLTE4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKHNlbGYsIGE6IEFzc2V0KSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE4NQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X25hbWUoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxODYKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9uYW1lKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXROYW1lCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTg3CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTg4CiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTg5CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTEtMTkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybChzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToxOTMKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF91cmwoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFVSTAogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5NAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3VybChfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VVJMCiAgICBjb3ZlciAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk1CiAgICAvLyBhc3NlcnQgdmFsdWUgPT0gdmFsdWVfaW5kZXgsICJleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCIKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk2CiAgICAvLyBhc3NlcnQgZXhpc3RzID09IGV4aXN0c19pbmRleCwgImV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCIKICAgIGNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTk3CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjE5OS0yMDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChzZWxmLCBhOiBBc3NldCkgLT4gQnl0ZXM6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDEKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tZXRhZGF0YV9oYXNoKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIHN3YXAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDIKICAgIC8vIHZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXggPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tZXRhZGF0YV9oYXNoKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDQKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDUKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMuYXJ0aWZhY3RzLlN0YXRlT3BzLmNvbnRyYWN0LlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjA3LTIwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyKHNlbGYsIGE6IEFzc2V0KSAtPiBhcmM0LkFkZHJlc3M6CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMDkKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBvcC5Bc3NldFBhcmFtc0dldC5hc3NldF9tYW5hZ2VyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNYW5hZ2VyCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjEwCiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfbWFuYWdlcihfZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgX2dldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0TWFuYWdlcgogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxMQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxMgogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxMwogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9yZXNlcnZlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxNS0yMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZShzZWxmLCBhOiBBc3NldCkgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjE3CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfcmVzZXJ2ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0UmVzZXJ2ZQogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIxOAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X3Jlc2VydmUoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFJlc2VydmUKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMTkKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjAKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjEKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZShhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjIzLTIyNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoc2VsZiwgYTogQXNzZXQpIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIyNQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2ZyZWV6ZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RnJlZXplCiAgICBzd2FwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjI2CiAgICAvLyB2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4ID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfZnJlZXplKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRGcmVlemUKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjcKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjgKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyMjkKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzMS0yMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2soc2VsZiwgYTogQXNzZXQpIC0+IGFyYzQuQWRkcmVzczoKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzMwogICAgLy8gdmFsdWUsIGV4aXN0cyA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2NsYXdiYWNrKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDbGF3YmFjawogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzNAogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2NsYXdiYWNrKF9nZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBfZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDbGF3YmFjawogICAgY292ZXIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzNQogICAgLy8gYXNzZXJ0IHZhbHVlID09IHZhbHVlX2luZGV4LCAiZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzNgogICAgLy8gYXNzZXJ0IGV4aXN0cyA9PSBleGlzdHNfaW5kZXgsICJleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2giCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzNwogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzLmFydGlmYWN0cy5TdGF0ZU9wcy5jb250cmFjdC5TdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcihhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jcmVhdG9yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjIzOS0yNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcihzZWxmLCBhOiBBc3NldCkgLT4gYXJjNC5BZGRyZXNzOgogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MjQxCiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gb3AuQXNzZXRQYXJhbXNHZXQuYXNzZXRfY3JlYXRvcihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0Q3JlYXRvcgogICAgc3dhcAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL1N0YXRlT3BzL2NvbnRyYWN0LnB5OjI0MgogICAgLy8gdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleCA9IG9wLkFzc2V0UGFyYW1zR2V0LmFzc2V0X2NyZWF0b3IoX2dldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIF9nZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldENyZWF0b3IKICAgIGNvdmVyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDMKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSB2YWx1ZV9pbmRleCwgImV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDQKICAgIC8vIGFzc2VydCBleGlzdHMgPT0gZXhpc3RzX2luZGV4LCAiZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoIgogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9TdGF0ZU9wcy9jb250cmFjdC5weToyNDUKICAgIC8vIHJldHVybiBhcmM0LkFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIK", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy5hcnRpZmFjdHMuU3RhdGVPcHMuY29udHJhY3QuU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvU3RhdGVPcHMvY29udHJhY3QucHk6MTUwCiAgICAvLyBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIGludCAxCiAgICByZXR1cm4K" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNgogICAgcHVzaGJ5dGVzcyAweGFkNzE5YTZmIDB4MWQ2MDMwMTMgMHg5ZmI3MzFjZCAweDBmNWE0OTExIDB4ZjViMzcwYzYgMHhjN2Q2YWY3NCAweDZiNzFhMjYzIDB4MzA0MGViYzggMHgxZDA3ZTg0NCAweDNlNDBjYjUwIDB4MzQwYzc4NmIgMHhlMzhhOTgxNSAvLyBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3RvdGFsKGFzc2V0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVjaW1hbHMoYXNzZXQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhc3NldClib29sIiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91bml0X25hbWUoYXNzZXQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGFzc2V0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGFzc2V0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhc3NldClieXRlW10iLCBtZXRob2QgInZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIoYXNzZXQpYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZShhc3NldClhZGRyZXNzIiwgbWV0aG9kICJ2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoYXNzZXQpYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2soYXNzZXQpYWRkcmVzcyIsIG1ldGhvZCAidmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcihhc3NldClhZGRyZXNzIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFsc19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlZmF1bHRfZnJvemVuX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZV9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybF9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2hfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZV9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemVfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2tfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcl9yb3V0ZUAxMwogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWxfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbl9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbgogICAgcHVzaGJ5dGVzIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWVfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbmFtZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQXNzZXRQYXJhbXNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF91cmwKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21ldGFkYXRhX2hhc2gKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X21hbmFnZXIKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmVfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2ZyZWV6ZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFja19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY2xhd2JhY2sKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3Jfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIwCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbChhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdG90YWw6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3LTE1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF90b3RhbChhOiBBc3NldCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTkKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0VG90YWwoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFRvdGFsCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldFRvdGFsKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VG90YWwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYyCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWNpbWFsczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjYtMTY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2RlY2ltYWxzKGE6IEFzc2V0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OAogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXREZWNpbWFscyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RGVjaW1hbHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjkKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RGVjaW1hbHMoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXREZWNpbWFscwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzEKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZGVmYXVsdF9mcm96ZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc1LTE3NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9kZWZhdWx0X2Zyb3plbihhOiBBc3NldCk6IGJvb2xlYW4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc3CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5Bc3NldFBhcmFtcy5hc3NldERlZmF1bHRGcm96ZW4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlZmF1bHRGcm96ZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzgKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RGVmYXVsdEZyb3plbihnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldERlZmF1bHRGcm96ZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgwCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdW5pdF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODQtMTg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VuaXRfbmFtZShhOiBBc3NldCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NgogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRVbml0TmFtZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VW5pdE5hbWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODcKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0VW5pdE5hbWUoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRVbml0TmFtZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxODkKICAgIC8vIGFzc2VydChleGlzdHMgPT09IGV4aXN0c19pbmRleCwgJ2V4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGV4aXN0cyBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X25hbWU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzLTE5NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9uYW1lKGE6IEFzc2V0KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk1CiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5Bc3NldFBhcmFtcy5hc3NldE5hbWUoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTYKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0TmFtZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE5hbWUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk4CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfdXJsKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDItMjAzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3VybChhOiBBc3NldCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNAogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRVcmwoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFVSTAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRVcmwoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRVUkwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDYKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA3CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDgKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tZXRhZGF0YV9oYXNoOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMS0yMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWV0YWRhdGFfaGFzaChhOiBBc3NldCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMwogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRNZXRhZGF0YUhhc2goYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE1ldGFkYXRhSGFzaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBleGlzdHNfaW5kZXhdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRNZXRhZGF0YUhhc2goZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRNZXRhZGF0YUhhc2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTUKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE2CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTcKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFzc2V0UGFyYW1zQ29udHJhY3QudmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcihhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9tYW5hZ2VyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMC0yMjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfbWFuYWdlcihhOiBBc3NldCk6IEFkZHJlc3MgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIyCiAgICAvLyBjb25zdCBbdmFsdWUsIGV4aXN0c10gPSBvcC5Bc3NldFBhcmFtcy5hc3NldE1hbmFnZXIoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE1hbmFnZXIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjMKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0TWFuYWdlcihnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldE1hbmFnZXIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjQKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI1CiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjYKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfcmVzZXJ2ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjktMjMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X3Jlc2VydmUoYTogQXNzZXQpOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzMQogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRSZXNlcnZlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRSZXNlcnZlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjMyCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldFJlc2VydmUoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRSZXNlcnZlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjMzCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNAogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM1CiAgICAvLyByZXR1cm4gbmV3IEFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9mcmVlemUoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzOC0yMzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfZnJlZXplKGE6IEFzc2V0KTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDAKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RnJlZXplKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRGcmVlemUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDEKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZXhpc3RzX2luZGV4XSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0RnJlZXplKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0RnJlZXplCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQyCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MwogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ0CiAgICAvLyByZXR1cm4gbmV3IEFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC52ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjayhhOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfYXNzZXRfcGFyYW1zX2dldF9jbGF3YmFjazoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDctMjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NsYXdiYWNrKGE6IEFzc2V0KTogQWRkcmVzcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDkKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZXhpc3RzXSA9IG9wLkFzc2V0UGFyYW1zLmFzc2V0Q2xhd2JhY2soYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldENsYXdiYWNrCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldENsYXdiYWNrKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0Q2xhd2JhY2sKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUyCiAgICAvLyBhc3NlcnQoZXhpc3RzID09PSBleGlzdHNfaW5kZXgsICdleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBleGlzdHMgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTMKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBc3NldFBhcmFtc0NvbnRyYWN0LnZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2Fzc2V0X3BhcmFtc19nZXRfY3JlYXRvcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNTYtMjU3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hc3NldF9wYXJhbXNfZ2V0X2NyZWF0b3IoYTogQXNzZXQpOiBBZGRyZXNzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1OAogICAgLy8gY29uc3QgW3ZhbHVlLCBleGlzdHNdID0gb3AuQXNzZXRQYXJhbXMuYXNzZXRDcmVhdG9yKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDcmVhdG9yCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU5CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGV4aXN0c19pbmRleF0gPSBvcC5Bc3NldFBhcmFtcy5hc3NldENyZWF0b3IoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRDcmVhdG9yCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYwCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MQogICAgLy8gYXNzZXJ0KGV4aXN0cyA9PT0gZXhpc3RzX2luZGV4LCAnZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZXhpc3RzIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYyCiAgICAvLyByZXR1cm4gbmV3IEFkZHJlc3ModmFsdWUpCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQXNzZXRQYXJhbXNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" }, "state": { "global": { diff --git a/tests/artifacts/state-ops/data/StateAssetParamsContract.arc56.json b/tests/artifacts/state-ops/data/StateAssetParamsContract.arc56.json new file mode 100644 index 0000000..af64086 --- /dev/null +++ b/tests/artifacts/state-ops/data/StateAssetParamsContract.arc56.json @@ -0,0 +1,382 @@ +{ + "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 index 21cbde0..fc0579b 100644 --- a/tests/artifacts/state-ops/data/StateAssetParamsContract.clear.teal +++ b/tests/artifacts/state-ops/data/StateAssetParamsContract.clear.teal @@ -1,7 +1,5 @@ #pragma version 10 -tests.artifacts.StateOps.contract.StateAssetParamsContract.clear_state_program: - // tests/artifacts/StateOps/contract.py:150 - // class StateAssetParamsContract(ARC4Contract): - int 1 +tests/artifacts/state-ops/contract.algo.ts::StateAssetParamsContract.clearStateProgram: + pushint 1 // 1 return diff --git a/tests/avm-invoker.ts b/tests/avm-invoker.ts index edd23ae..4c6713a 100644 --- a/tests/avm-invoker.ts +++ b/tests/avm-invoker.ts @@ -1,6 +1,6 @@ import * as algokit from '@algorandfoundation/algokit-utils' import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' -import { ABIAppCallArg, ABIReturn } from '@algorandfoundation/algokit-utils/types/app' +import { ABIAppCallArg, AppCallTransactionResult } from '@algorandfoundation/algokit-utils/types/app' import { ApplicationClient } from '@algorandfoundation/algokit-utils/types/app-client' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { KmdAccountManager } from '@algorandfoundation/algokit-utils/types/kmd-account-manager' @@ -35,13 +35,13 @@ const invokeMethod = async ( method: string, sendParams?: SendTransactionParams, ...methodArgs: ABIAppCallArg[] -): Promise => { +): Promise => { const response = await appClient.call({ method, methodArgs, note: randomUUID(), sendParams }) if (response.return?.decodeError) { throw response.return.decodeError } - return response.return + return response } export const getAvmResult = async ( @@ -50,7 +50,16 @@ export const getAvmResult = async ( ...methodArgs: ABIAppCallArg[] ): Promise => { const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) - return result?.returnValue as TResult + return result?.return?.returnValue as TResult +} + +export const getAvmResultLog = async ( + { appClient, sendParams }: { appClient: ApplicationClient; sendParams?: SendTransactionParams }, + method: string, + ...methodArgs: ABIAppCallArg[] +): Promise => { + const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) + return result?.confirmation?.logs } export const getAvmResultRaw = async ( @@ -59,7 +68,7 @@ export const getAvmResultRaw = async ( ...methodArgs: ABIAppCallArg[] ): Promise => { const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) - return result?.rawReturnValue + return result?.return?.rawReturnValue } export const getLocalNetDefaultAccount = () => { diff --git a/tests/global-state-arc4-values.spec.ts b/tests/global-state-arc4-values.spec.ts new file mode 100644 index 0000000..e7900d3 --- /dev/null +++ b/tests/global-state-arc4-values.spec.ts @@ -0,0 +1,124 @@ +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { + 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 { 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 { asUint8Array } from './util' + +describe('ARC4 AppGlobal values', async () => { + const appClient = await getAlgorandAppClient(arc4AppGlobalAppSpecJson as AppSpec) + const localNetAccount = await getLocalNetDefaultAccount() + const defaultSenderAccountAddress = Bytes.fromBase32(localNetAccount.addr) + const ctx = new TestExecutionContext(defaultSenderAccountAddress) + + afterEach(async () => { + ctx.reset() + }) + + const testData = ['_implicit_key', ''].flatMap((implicit) => [ + { + nativeValue: 42, + abiValue: new UintN<64>(42), + methodName: `get${implicit}_arc4_uintn64`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as UintNImpl + const bitSize = UintNImpl.getMaxBitsLength(arc4Value.typeInfo) + expect(arc4Value).toBeInstanceOf(UintN) + expect(bitSize).toEqual(64) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + nativeValue: 'World', + abiValue: new Str('World'), + methodName: `get${implicit}_arc4_str`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as StrImpl + expect(arc4Value).toBeInstanceOf(Str) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + nativeValue: 12, + abiValue: new Byte(12), + methodName: `get${implicit}_arc4_byte`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as ByteImpl + expect(arc4Value).toBeInstanceOf(Byte) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + nativeValue: false, + abiValue: new Bool(false), + methodName: `get${implicit}_arc4_bool`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as BoolImpl + expect(arc4Value).toBeInstanceOf(Bool) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + nativeValue: asUint8Array(Bytes.fromHex(`${'00'.repeat(31)}ff`)), + abiValue: new Address(Bytes.fromHex(`${'00'.repeat(31)}ff`)), + methodName: `get${implicit}_arc4_address`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as AddressImpl + expect(arc4Value).toBeInstanceOf(Address) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + nativeValue: 2n ** 102n, + abiValue: new UintN<128>(2n ** 102n), + methodName: `get${implicit}_arc4_uintn128`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as UintNImpl + const bitSize = UintNImpl.getMaxBitsLength(arc4Value.typeInfo) + expect(arc4Value).toBeInstanceOf(UintN) + expect(bitSize).toEqual(128) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + nativeValue: asUint8Array(Bytes.fromHex(`${'00'.repeat(30)}${'ff'.repeat(2)}`)), + abiValue: new DynamicBytes(Bytes.fromHex(`${'00'.repeat(30)}${'ff'.repeat(2)}`)), + methodName: `get${implicit}_arc4_dynamic_bytes`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as DynamicBytesImpl + expect(arc4Value).toBeInstanceOf(DynamicBytes) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + ]) + + test.each(testData)('should be able to get arc4 state values', async (data) => { + 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) => { + const setMethodName = data.methodName.replace('get', 'set') + await getAvmResult({ appClient }, setMethodName, data.nativeValue) + const contract = ctx.contract.create(GlobalStateContract) + contract[setMethodName as FunctionKeys](data.abiValue as never) + + const avmResult = await getAvmResult({ appClient }, data.methodName) + const result = contract[data.methodName as FunctionKeys](undefined as never) as ARC4Encoded + data.assert(result, avmResult) + }) +}) diff --git a/tests/local-state-arc4-values.spec.ts b/tests/local-state-arc4-values.spec.ts new file mode 100644 index 0000000..c214378 --- /dev/null +++ b/tests/local-state-arc4-values.spec.ts @@ -0,0 +1,111 @@ +import { ApplicationClient } from '@algorandfoundation/algokit-utils/types/app-client' +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { Account, Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { + 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 } 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' + +describe('ARC4 AppLocal values', async () => { + const appClient = await getAlgorandAppClient(arc4AppLocalAppSpecJson as AppSpec) + const localNetAccount = await getLocalNetDefaultAccount() + const defaultSenderAccountAddress = Bytes.fromBase32(localNetAccount.addr) + const ctx = new TestExecutionContext(defaultSenderAccountAddress) + await tryOptIn(appClient) + + afterEach(async () => { + ctx.reset() + }) + + const testData = ['_implicit_key', ''].flatMap((implicit) => [ + { + methodName: `get${implicit}_arc4_uintn64`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as UintNImpl + const bitSize = UintNImpl.getMaxBitsLength(arc4Value.typeInfo) + expect(arc4Value).toBeInstanceOf(UintN) + expect(bitSize).toEqual(64) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + methodName: `get${implicit}_arc4_str`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as StrImpl + expect(arc4Value).toBeInstanceOf(Str) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + methodName: `get${implicit}_arc4_byte`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as ByteImpl + expect(arc4Value).toBeInstanceOf(Byte) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + methodName: `get${implicit}_arc4_bool`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as BoolImpl + expect(arc4Value).toBeInstanceOf(Bool) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + methodName: `get${implicit}_arc4_address`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as AddressImpl + expect(arc4Value).toBeInstanceOf(Address) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + methodName: `get${implicit}_arc4_uintn128`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as UintNImpl + const bitSize = UintNImpl.getMaxBitsLength(arc4Value.typeInfo) + expect(arc4Value).toBeInstanceOf(UintN) + expect(bitSize).toEqual(128) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + { + methodName: `get${implicit}_arc4_dynamic_bytes`, + assert: (value: ARC4Encoded, expectedValue: DeliberateAny) => { + const arc4Value = value as DynamicBytesImpl + expect(arc4Value).toBeInstanceOf(DynamicBytes) + expect(arc4Value.native).toEqual(expectedValue) + }, + }, + ]) + + test.each(testData)('should be able to get arc4 state values', async (data) => { + const avmResult = await getAvmResult({ appClient }, data.methodName, localNetAccount.addr) + 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: ApplicationClient) => { + try { + await client.optIn({ method: 'opt_in', methodArgs: [] }) + } catch (e) { + if (!(e as DeliberateAny).message.includes('has already opted in to app')) { + throw e + } + // ignore error if account has already opted in + } +} diff --git a/tests/log.spec.ts b/tests/log.spec.ts new file mode 100644 index 0000000..4d29ddd --- /dev/null +++ b/tests/log.spec.ts @@ -0,0 +1,82 @@ +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 { + Bool, + DynamicArray, + StaticArray, + Str, + Tuple, + UFixedNxM, + UintN, + UintN16, + UintN32, + UintN64, + UintN8, +} from '@algorandfoundation/algorand-typescript/arc4' +import { afterEach, describe, expect, it } from 'vitest' +import { MAX_UINT512, MAX_UINT64 } from '../src/constants' +import { ApplicationTransaction } from '../src/impl/transactions' +import { asBigUint, asBigUintCls } 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 { asUint8Array } from './util' + +describe('log', async () => { + const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const ctx = new TestExecutionContext() + + afterEach(async () => { + ctx.reset() + }) + + it('should log different data types', async () => { + const a = 'hello' + const b = Uint64(MAX_UINT64) + const c = Bytes('world') + const d = BigInt(MAX_UINT512) + const e = new Bool(true) + const f = new Str('greetings') + const g = new UintN<64>(42) + const h = new UintN<256>(512) + const i = new UFixedNxM<32, 8>('42.94967295') + const j = new UFixedNxM<256, 16>('25.5') + const k = new StaticArray(new UintN8(1), new UintN8(2), new UintN8(3)) + const m = new DynamicArray(new UintN16(1), new UintN16(2), new UintN16(3)) + const n = new Tuple((new UintN32(1), new UintN64(2), new Str('hello'))) + + const avmResult = await getAvmResultLog( + { appClient }, + 'verify_log', + a, + b.valueOf(), + asUint8Array(c), + asUint8Array(asBigUintCls(d).toBytes()), + e.native, + f.native, + g.native.valueOf(), + h.native.valueOf(), + asBigUint(i.bytes).valueOf(), + asBigUint(j.bytes).valueOf(), + asUint8Array(k.bytes), + asUint8Array(m.bytes), + asUint8Array(n.bytes), + ) + expect(Array.isArray(avmResult)).toBeTruthy() + ctx.txn.createScope([ctx.any.txn.payment()]).execute(() => { + expect(() => log(a, b, c, d, e, f, g, h, i, j, k, m, n)).toThrow('Can only add logs to ApplicationCallTransaction') + }) + const dummyApp = ctx.any.application() + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: dummyApp })]).execute(() => { + log(a, b, c, d, e, f, g, h, i, j, k, m, n) + }) + let lastTxn = ctx.txn.lastActive as ApplicationTransaction + expect(lastTxn.appLogs).toEqual(avmResult) + + const contract = ctx.contract.create(PrimitiveOpsContract) + contract.verify_log(a, b, c, asBigUintCls(d).toBytes().asAlgoTs(), e, f, g, h, i, j, k.bytes, m.bytes, n.bytes) + lastTxn = ctx.txn.lastActive as ApplicationTransaction + expect(lastTxn.appLogs).toEqual(avmResult) + }) +}) diff --git a/tests/references/box-map.spec.ts b/tests/references/box-map.spec.ts index 32ebbdb..82bbed2 100644 --- a/tests/references/box-map.spec.ts +++ b/tests/references/box-map.spec.ts @@ -1,39 +1,103 @@ import { biguint, BigUint, BoxMap, Bytes, bytes, op, uint64, 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 { MAX_UINT64 } from '../../src/constants' import { DeliberateAny } from '../../src/typescript-helpers' -import { asBigUintCls, asBytes, asUint64Cls, toBytes } from '../../src/util' +import { asBytes, toBytes } from '../../src/util' const BOX_NOT_CREATED_ERROR = 'Box has not been created' describe('BoxMap', () => { const ctx = new TestExecutionContext() const keyPrefix = Bytes('test_key_prefix') - const testUint64BoxMap = (test: (boxMap: BoxMap) => void) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const boxMap = BoxMap({ keyPrefix }) - test(boxMap) - }) - } - const testBytesBoxMap = (test: (boxMap: BoxMap) => void) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const boxMap = BoxMap({ keyPrefix }) - test(boxMap) - }) - } - const testStringBoxMap = (test: (boxMap: BoxMap) => void) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const boxMap = BoxMap({ keyPrefix }) - test(boxMap) - }) - } - const testBigUintBoxMap = (test: (boxMap: BoxMap) => void) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const boxMap = BoxMap({ keyPrefix }) - test(boxMap) - }) - } + const testData = [ + { + key: Bytes('abc'), + value: Uint64(100), + newValue: Uint64(200), + emptyValue: Uint64(0), + withBoxContext: (test: (boxMap: BoxMap) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap({ keyPrefix }) + test(boxMap) + }) + }, + }, + { + key: 'def', + value: Bytes('Test1'), + newValue: Bytes('hello'), + emptyValue: Bytes(''), + withBoxContext: (test: (boxMap: BoxMap) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap({ keyPrefix }) + test(boxMap) + }) + }, + }, + { + key: BigUint(123), + value: 'Test1', + newValue: 'hello', + emptyValue: '', + withBoxContext: (test: (boxMap: BoxMap) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap({ keyPrefix }) + test(boxMap) + }) + }, + }, + { + key: Uint64(456), + value: BigUint(MAX_UINT64), + newValue: BigUint(MAX_UINT64 - 1n), + emptyValue: BigUint(0), + withBoxContext: (test: (boxMap: BoxMap) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap({ keyPrefix }) + test(boxMap) + }) + }, + }, + { + key: new Str('ghi'), + value: BigUint(100), + newValue: BigUint(200), + emptyValue: BigUint(0), + withBoxContext: (test: (boxMap: BoxMap) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap({ keyPrefix }) + test(boxMap) + }) + }, + }, + { + key: Uint64(456), + value: new Str('Test1'), + newValue: new Str('hello'), + emptyValue: interpretAsArc4(Bytes('')), + withBoxContext: (test: (boxMap: BoxMap) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap({ keyPrefix }) + test(boxMap) + }) + }, + }, + { + key: new Str('jkl'), + value: new DynamicArray(new UintN64(100), new UintN64(200)), + newValue: new DynamicArray(new UintN64(200), new UintN64(300)), + emptyValue: interpretAsArc4>(Bytes('')), + withBoxContext: (test: (boxMap: BoxMap>) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = BoxMap>({ keyPrefix }) + test(boxMap) + }) + }, + }, + ] + afterEach(() => { ctx.reset() }) @@ -49,14 +113,8 @@ describe('BoxMap', () => { }) }) - // TODO: add tests for settign arc4 types as value - test.each([ - [Bytes('abc'), Uint64(100), testUint64BoxMap], - ['def', Bytes('Test'), testBytesBoxMap], - [BigUint(123), 'Test', testStringBoxMap], - [Uint64(456), BigUint(MAX_UINT64), testBigUintBoxMap], - ])('key %s and value %s can be set as value', (key, value, testBoxMap) => { - testBoxMap((boxMap) => { + 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) const boxContent = (boxMap as DeliberateAny).get(key) @@ -71,14 +129,8 @@ describe('BoxMap', () => { }) }) - // TODO: add tests for settign arc4 types as value - test.each([ - [Bytes('abc'), Uint64(100), testUint64BoxMap], - ['def', Bytes('Test'), testBytesBoxMap], - [BigUint(123), 'Test', testStringBoxMap], - [Uint64(456), BigUint(MAX_UINT64), testBigUintBoxMap], - ])('key %s and value %s can be delete', (key, value, testBoxMap) => { - testBoxMap((boxMap) => { + 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.delete(key as never) @@ -91,14 +143,8 @@ describe('BoxMap', () => { }) }) - // TODO: add tests for settign arc4 types as value - test.each([ - [Bytes('abc'), Uint64(100), testUint64BoxMap], - ['def', Bytes('Test'), testBytesBoxMap], - [BigUint(123), 'Test', testStringBoxMap], - [Uint64(456), BigUint(MAX_UINT64), testBigUintBoxMap], - ])('can retrieve existing key %s and value %s using maybe', (key, value, testBoxMap) => { - testBoxMap((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) const [content, exists] = boxMap.maybe(key as never) @@ -114,21 +160,19 @@ describe('BoxMap', () => { }) }) - // TODO: add tests for settign arc4 types as value - test.each([ - [Bytes('abc'), Uint64(100), Uint64(0), testUint64BoxMap], - ['def', Bytes('Test'), Bytes(''), testBytesBoxMap], - [BigUint(123), 'Test', '', testStringBoxMap], - [Uint64(456), BigUint(MAX_UINT64), BigUint(0), testBigUintBoxMap], - ])('can retrieve non-existing value using maybe', (key, value, expectedEmptyValue, testBoxMap) => { - testBoxMap((boxMap) => { + 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) const [content, exists] = boxMap.maybe(key as never) expect(exists).toBe(false) - expect(content).toEqual(expectedEmptyValue) + if (content instanceof ARC4Encoded) { + expect(content.bytes).toEqual((emptyValue as ARC4Encoded).bytes) + } else { + expect(content).toEqual(emptyValue) + } const fullKey = keyPrefix.concat(toBytes(key)) const [opContent, opExists] = op.Box.get(fullKey) @@ -137,22 +181,26 @@ describe('BoxMap', () => { }) }) - test.each([ - [Bytes('abc'), Uint64(100), Uint64(200), asUint64Cls(200).toBytes().asAlgoTs(), testUint64BoxMap], - ['def', Bytes('Test1'), Bytes('hello'), Bytes('hello'), testBytesBoxMap], - [BigUint(123), 'Test1', 'hello', Bytes('hello'), testStringBoxMap], - [Uint64(456), BigUint(100), BigUint(200), asBigUintCls(200).toBytes().asAlgoTs(), testBigUintBoxMap], - ])('can get typed value after using op.Box.put', (key, value, newValue, newBytesValue, testBoxMap) => { - testBoxMap((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) - expect((boxMap as DeliberateAny).get(key)).toEqual(value) + if (value instanceof ARC4Encoded) { + expect((boxMap as DeliberateAny).get(key).bytes).toEqual(value.bytes) + } else { + expect((boxMap as DeliberateAny).get(key)).toEqual(value) + } + const newBytesValue = toBytes(newValue) const fullKey = keyPrefix.concat(toBytes(key)) op.Box.put(fullKey, newBytesValue) const [opContent, _] = op.Box.get(fullKey) expect(opContent).toEqual(newBytesValue) - expect((boxMap as DeliberateAny).get(key)).toEqual(newValue) + if (newValue instanceof ARC4Encoded) { + expect((boxMap as DeliberateAny).get(key).bytes).toEqual(newValue.bytes) + } else { + expect((boxMap as DeliberateAny).get(key)).toEqual(newValue) + } }) }) }) diff --git a/tests/references/box.spec.ts b/tests/references/box.spec.ts index b61dfce..e68d5af 100644 --- a/tests/references/box.spec.ts +++ b/tests/references/box.spec.ts @@ -1,8 +1,10 @@ import { BigUint, biguint, Box, bytes, Bytes, op, uint64, 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 { asBigUintCls, asBytes, asUint64Cls, toBytes } from '../../src/util' +import { DeliberateAny } from '../../src/typescript-helpers' +import { asBytes, toBytes } from '../../src/util' import { BoxContract } from '../artifacts/box-contract/contract.algo' const BOX_NOT_CREATED_ERROR = 'Box has not been created' @@ -10,36 +12,85 @@ const BOX_NOT_CREATED_ERROR = 'Box has not been created' describe('Box', () => { const ctx = new TestExecutionContext() const key = Bytes('test_key') - const testUint64Box = (test: (box: Box) => void) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const box = Box({ key }) - test(box) - }) - } - const testBytesBox = (test: (box: Box) => void) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const box = Box({ key }) - test(box) - }) - } - const testStringBox = (test: (box: Box) => void) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const box = Box({ key }) - test(box) - }) - } - const testBigUintBox = (test: (box: Box) => void) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const box = Box({ key }) - test(box) - }) - } - const testBooleanBox = (test: (box: Box) => void) => { - ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { - const box = Box({ key }) - test(box) - }) - } + const testData = [ + { + value: Uint64(100), + newValue: Uint64(200), + emptyValue: Uint64(0), + withBoxContext: (test: (box: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + test(box) + }) + }, + }, + { + value: Bytes('Test1'), + newValue: Bytes('hello'), + emptyValue: Bytes(''), + withBoxContext: (test: (box: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + test(box) + }) + }, + }, + { + value: 'Test1', + newValue: 'hello', + emptyValue: '', + withBoxContext: (test: (box: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + test(box) + }) + }, + }, + { + value: BigUint(100), + newValue: BigUint(200), + emptyValue: BigUint(0), + withBoxContext: (test: (box: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + test(box) + }) + }, + }, + { + value: true, + newValue: false, + emptyValue: false, + withBoxContext: (test: (box: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const box = Box({ key }) + test(box) + }) + }, + }, + { + value: new Str('Test1'), + newValue: new Str('hello'), + emptyValue: interpretAsArc4(Bytes('')), + withBoxContext: (test: (boxMap: Box) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = Box({ key }) + test(boxMap) + }) + }, + }, + { + value: new DynamicArray(new UintN64(100), new UintN64(200)), + newValue: new DynamicArray(new UintN64(200), new UintN64(300)), + emptyValue: interpretAsArc4>(Bytes('')), + withBoxContext: (test: (boxMap: Box>) => void) => { + ctx.txn.createScope([ctx.any.txn.applicationCall()]).execute(() => { + const boxMap = Box>({ key }) + test(boxMap) + }) + }, + }, + ] afterEach(() => { ctx.reset() @@ -55,14 +106,8 @@ describe('Box', () => { }) }) - // TODO: add tests for settign arc4 types as value - test.each([ - [Uint64(100), testUint64Box], - [Bytes('Test'), testBytesBox], - ['Test', testStringBox], - [BigUint(100), testBigUintBox], - ])('%s can be set as value', (value, testBox) => { - testBox((box) => { + test.each(testData)('%s can be set as value', ({ value, withBoxContext }) => { + withBoxContext((box) => { box.value = value const [content, exists] = op.Box.get(key) @@ -74,14 +119,8 @@ describe('Box', () => { }) }) - // // TODO: add tests for settign arc4 types as value - test.each([ - [Uint64(100), testUint64Box], - [Bytes('Test'), testBytesBox], - ['Test', testStringBox], - [BigUint(100), testBigUintBox], - ])('%s value can be delete', (value, testBox) => { - testBox((box) => { + test.each(testData)('%s value can be delete', ({ value, withBoxContext }) => { + withBoxContext((box) => { box.value = value box.delete() @@ -95,14 +134,8 @@ describe('Box', () => { }) }) - // // TODO: add tests for settign arc4 types as value - test.each([ - [Uint64(100), testUint64Box], - [Bytes('Test'), testBytesBox], - ['Test', testStringBox], - [BigUint(100), testBigUintBox], - ])('can retrieve existing value %s using maybe', (value, testBox) => { - testBox((box) => { + test.each(testData)('can retrieve existing value %s using maybe', ({ value, withBoxContext }) => { + withBoxContext((box) => { box.value = value const [content, exists] = box.maybe() @@ -114,14 +147,8 @@ describe('Box', () => { }) }) - // // TODO: add tests for settign arc4 types as value - test.each([ - [Uint64(100), testUint64Box, Uint64(0)], - [Bytes('Test'), testBytesBox, Bytes('')], - ['Test', testStringBox, ''], - [BigUint(100), testBigUintBox, BigUint(0)], - ])('can retrieve non-existing value using maybe', (value, testBox, expectedValue) => { - testBox((box) => { + test.each(testData)('can retrieve non-existing value using maybe', ({ value, emptyValue, withBoxContext }) => { + withBoxContext((box) => { box.value = value box.delete() @@ -131,7 +158,11 @@ describe('Box', () => { expect(exists).toBe(false) expect(opExists).toBe(false) expect(opContent).toEqual(Bytes('')) - expect(content).toEqual(expectedValue) + if (content instanceof ARC4Encoded) { + expect(content.bytes).toEqual((emptyValue as ARC4Encoded).bytes) + } else { + expect(content).toEqual(emptyValue) + } }) }) @@ -143,30 +174,33 @@ describe('Box', () => { ctx.txn.createScope([deferredStoreCall, deferredReadCall]).execute(() => { deferredStoreCall.submit() - const [oca, txn] = deferredReadCall.submit() + const [oca, txn] = deferredReadCall.submit().native const app = ctx.ledger.getApplicationForContract(contract) - expect(toBytes(ctx.ledger.getBox(app, 'oca'))).toEqual(itob(oca)) - expect(toBytes(ctx.ledger.getBox(app, 'txn'))).toEqual(itob(txn)) + expect(toBytes(ctx.ledger.getBox(app, 'oca'))).toEqual(itob(oca.native)) + expect(toBytes(ctx.ledger.getBox(app, 'txn'))).toEqual(itob(txn.native)) }) }) - test.each([ - [Uint64(100), Uint64(200), asUint64Cls(200).toBytes().asAlgoTs(), testUint64Box], - [BigUint(100), BigUint(200), asBigUintCls(200).toBytes().asAlgoTs(), testBigUintBox], - [Bytes('abc'), Bytes('def'), Bytes('def'), testBytesBox], - ['abc', 'def', Bytes('def'), testStringBox], - [true, false, asUint64Cls(0).toBytes().asAlgoTs(), testBooleanBox], - ])('can get typed value after using op.Box.put', (value, newValue, newBytesValue, testBox) => { - testBox((box) => { + test.each(testData)('can get typed value after using op.Box.put', ({ value, newValue, withBoxContext }) => { + withBoxContext((box) => { box.value = value - expect(box.value).toEqual(value) + if (value instanceof ARC4Encoded) { + expect((box as DeliberateAny).get(key).bytes).toEqual(value.bytes) + } else { + expect(box.value).toEqual(value) + } + const newBytesValue = toBytes(newValue) op.Box.put(key, newBytesValue) const [opContent, _] = op.Box.get(key) expect(opContent).toEqual(newBytesValue) - expect(box.value).toEqual(newValue) + if (newValue instanceof ARC4Encoded) { + expect((box as DeliberateAny).get(key).bytes).toEqual(newValue.bytes) + } else { + expect(box.value).toEqual(newValue) + } }) }) }) diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 7fa0ade..cac8190 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -2,10 +2,12 @@ import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import { ApplicationClient } 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 { DynamicBytes } from '@algorandfoundation/algorand-typescript/arc4' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' import { MIN_TXN_FEE, ZERO_ADDRESS } from '../src/constants' 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' @@ -42,7 +44,6 @@ import { INITIAL_BALANCE_MICRO_ALGOS, } from './avm-invoker' import { asUint8Array } from './util' -import { Block, gloadBytes, gloadUint64 } from '../src/impl' describe('State op codes', async () => { const ctx = new TestExecutionContext() @@ -491,7 +492,7 @@ describe('State op codes', async () => { const secondContract = ctx.contract.create(StateAppGlobalExContract) const secondApp = ctx.ledger.getApplicationForContract(secondContract) expect(secondApp.globalNumUint.valueOf()).toEqual(2) - expect(secondApp.globalNumBytes.valueOf()).toEqual(2) + expect(secondApp.globalNumBytes.valueOf()).toEqual(4) const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_ex_bytes', exApp.appId, asUint8Array(key)) @@ -501,20 +502,25 @@ describe('State op codes', async () => { expect(bytesResult).toEqual(bytesAvmResult) }) - // TODO: implement test_app_global_ex_get_arc4 test method when arc4 stubs are implemented + test.each(['global_arc4_bytes_explicit', 'global_arc4_bytes'])( + 'should be able to use _ex methods to get arc4 state values of another app', + async (key) => { + const secondContract = ctx.contract.create(StateAppGlobalExContract) + const secondApp = ctx.ledger.getApplicationForContract(secondContract) + expect(secondApp.globalNumUint.valueOf()).toEqual(2) + expect(secondApp.globalNumBytes.valueOf()).toEqual(4) + + const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_ex_bytes', exApp.appId, asUint8Array(key)) + + const contract = ctx.contract.create(StateAppGlobalContract) + const bytesResult = contract.verify_get_ex_bytes(secondApp, Bytes(key)) + + expect(bytesResult).toEqual(bytesAvmResult) + }, + ) }) describe('AppLocal', async () => { - const tryOptIn = async (client: ApplicationClient) => { - try { - await client.optIn({ method: 'opt_in', methodArgs: [] }) - } catch (e) { - if (!(e as DeliberateAny).message.includes('has already opted in to app')) { - throw e - } - // ignore error if account has already opted in - } - } const appClient = await getAlgorandAppClient(appLocalAppSpecJson as AppSpec) const [exAppClient, exApp] = await getAlgorandAppClientWithApp(appLocalExAppSpecJson as AppSpec) await tryOptIn(appClient) @@ -566,7 +572,7 @@ describe('State op codes', async () => { const secondContract = ctx.contract.create(StateAppLocalExContract) const secondApp = ctx.ledger.getApplicationForContract(secondContract) expect(secondApp.localNumUint.valueOf()).toEqual(1) - expect(secondApp.localNumBytes.valueOf()).toEqual(1) + expect(secondApp.localNumBytes.valueOf()).toEqual(2) const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_ex_bytes', localNetAccount.addr, exApp.appId, asUint8Array(key)) @@ -577,6 +583,32 @@ describe('State op codes', async () => { expect(bytesResult).toEqual(bytesAvmResult) }) - // TODO: implement test_app_local_ex_get_arc4 test method when arc4 stubs are implemented + it('should be able to use _ex methods to get arc4 state values of another app', async () => { + const key = 'local_arc4_bytes' + const localNetAccount = await getLocalNetDefaultAccount() + const account = Account(Bytes.fromBase32(localNetAccount.addr)) + const secondContract = ctx.contract.create(StateAppLocalExContract) + const secondApp = ctx.ledger.getApplicationForContract(secondContract) + expect(secondApp.localNumUint.valueOf()).toEqual(1) + expect(secondApp.localNumBytes.valueOf()).toEqual(2) + + const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_ex_bytes', localNetAccount.addr, exApp.appId, asUint8Array(key)) + + const contract = ctx.contract.create(StateAppLocalContract) + secondContract.localArc4Bytes(account).value = new DynamicBytes('dummy_arc4_bytes') + const bytesResult = contract.verify_get_ex_bytes(account, secondApp, Bytes(key)) + + expect(bytesResult).toEqual(bytesAvmResult) + }) }) }) +const tryOptIn = async (client: ApplicationClient) => { + try { + await client.optIn({ method: 'opt_in', methodArgs: [] }) + } catch (e) { + if (!(e as DeliberateAny).message.includes('has already opted in to app')) { + throw e + } + // ignore error if account has already opted in + } +} From 81833aff3fb87bc39bbcdc90bc7054ee1a80c8a1 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 12 Dec 2024 18:41:29 +0800 Subject: [PATCH 66/85] feat: implement method signatures and method selectors --- src/abi-metadata.ts | 62 +++++++++++++++---- src/impl/encoded-types.ts | 59 ++++++++++++++++++ src/subcontexts/contract-context.ts | 19 +++--- src/subcontexts/transaction-context.ts | 4 +- src/test-transformer/node-factory.ts | 13 ++-- src/test-transformer/visitors.ts | 6 +- .../created-app-asset/contract.algo.ts | 15 ++--- tests/state-op-codes.spec.ts | 18 ++---- 8 files changed, 142 insertions(+), 54 deletions(-) diff --git a/src/abi-metadata.ts b/src/abi-metadata.ts index d11dc57..be17f1a 100644 --- a/src/abi-metadata.ts +++ b/src/abi-metadata.ts @@ -1,10 +1,13 @@ import { BaseContract, Contract } from '@algorandfoundation/algorand-typescript' import { AbiMethodConfig, BareMethodConfig, CreateOptions, OnCompleteActionStr } from '@algorandfoundation/algorand-typescript/arc4' +import { ABIMethod } from 'algosdk' +import { TypeInfo } from './encoders' +import { getArc4TypeName as getArc4TypeNameForARC4Encoded } from './impl/encoded-types' import { DeliberateAny } from './typescript-helpers' export interface AbiMetadata { methodName: string - methodSelector: string + methodSignature: string | undefined argTypes: string[] returnType: string onCreate?: CreateOptions @@ -28,21 +31,11 @@ export const captureMethodConfig = ( methodName: string, config?: AbiMethodConfig | BareMethodConfig, ): void => { - const metadata = ensureMetadata(contract, methodName) + const metadata = getAbiMetadata(contract, methodName) metadata.onCreate = config?.onCreate ?? 'disallow' metadata.allowActions = ([] as OnCompleteActionStr[]).concat(config?.allowActions ?? 'NoOp') } -const ensureMetadata = (contract: T, methodName: string): AbiMetadata => { - if (!hasAbiMetadata(contract)) { - const contractClass = contract.constructor as { new (): T } - Object.getOwnPropertyNames(Object.getPrototypeOf(contract)).forEach((name) => { - attachAbiMetadata(contractClass, name, { methodName: name, methodSelector: name, argTypes: [], returnType: '' }) - }) - } - return getAbiMetadata(contract, methodName) -} - export const hasAbiMetadata = (contract: T): boolean => { const contractClass = contract.constructor as { new (): T } return ( @@ -58,3 +51,48 @@ export const getAbiMetadata = (contract: T, methodName: ) as Record return metadatas[methodName] } + +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) + const method = new ABIMethod({ name: metadata.methodName, args: argTypes.map((t) => ({ type: t })), returns: { type: returnType } }) + metadata.methodSignature = method.getSignature() + } + return metadata.methodSignature +} + +const getArc4TypeName = (t: TypeInfo): string => { + const map: Record string)> = { + void: 'void', + account: 'account', + application: 'application', + asset: 'asset', + boolean: 'bool', + biguint: 'uint512', + bytes: 'byte[]', + string: 'string', + uint64: 'uint64', + OnCompleteAction: 'uint64', + TransactionType: 'uint64', + Transaction: 'txn', + PaymentTxn: 'pay', + KeyRegistrationTxn: 'keyreg', + AssetConfigTxn: 'acfg', + AssetTransferTxn: 'axfer', + AssetFreezeTxn: 'afrz', + ApplicationTxn: 'appl', + 'Tuple<.*>': (t) => + `(${Object.values(t.genericArgs as Record) + .map(getArc4TypeName) + .join(',')})`, + } + const entry = Object.entries(map).find(([k, _]) => new RegExp(`^${k}$`, 'i').test(t.name))?.[1] + if (entry === undefined) { + return getArc4TypeNameForARC4Encoded(t) ?? t.name + } + if (entry instanceof Function) { + return entry(t) + } + return entry +} diff --git a/src/impl/encoded-types.ts b/src/impl/encoded-types.ts index cf8578b..178a991 100644 --- a/src/impl/encoded-types.ts +++ b/src/impl/encoded-types.ts @@ -81,6 +81,10 @@ export class UintNImpl extends UintN { static getMaxBitsLength(typeInfo: TypeInfo): BitSize { return parseInt((typeInfo.genericArgs as TypeInfo[])![0].name, 10) as BitSize } + + static getArc4TypeName = (t: TypeInfo): string => { + return `uint${this.getMaxBitsLength(t)}` + } } const regExpNxM = (maxPrecision: number) => new RegExp(`^\\d*\\.?\\d{0,${maxPrecision}}$`) @@ -144,6 +148,11 @@ export class UFixedNxMImpl extends UFixedNx const genericArgs = typeInfo.genericArgs as uFixedNxMGenericArgs return parseInt(genericArgs.n.name, 10) as BitSize } + + static getArc4TypeName = (t: TypeInfo): string => { + const genericArgs = t.genericArgs as uFixedNxMGenericArgs + return `ufixed${genericArgs.n.name}x${genericArgs.m.name}` + } } export class ByteImpl extends Byte { @@ -403,6 +412,11 @@ export class StaticArrayImpl } return size } + + static getArc4TypeName = (t: TypeInfo): string => { + const genericArgs = t.genericArgs as StaticArrayGenericArgs + return `${getArc4TypeName(genericArgs.elementType)}[${genericArgs.size.name}]` + } } export class AddressImpl extends Address { @@ -562,6 +576,11 @@ export class DynamicArrayImpl extends DynamicArray { + const genericArgs = t.genericArgs as DynamicArrayGenericArgs + return `${getArc4TypeName(genericArgs.elementType)}[]` + } + private encodeWithLength(items: TItem[]) { return conactUint8Arrays(encodeLength(items.length).asUint8Array(), encode(items)) } @@ -657,6 +676,11 @@ export class TupleImpl extends T } return size } + + static getArc4TypeName = (t: TypeInfo): string => { + const genericArgs = Object.values(t.genericArgs as Record) + return `(${genericArgs.map(getArc4TypeName).join(',')})` + } } type StructConstraint = Record @@ -732,6 +756,11 @@ export class StructImpl extends (Struct { + const genericArgs = Object.values(t.genericArgs as Record) + return `(${genericArgs.map(getArc4TypeName).join(',')})` + } } export class DynamicBytesImpl extends DynamicBytes { @@ -783,6 +812,10 @@ export class DynamicBytesImpl extends DynamicBytes { result.value = dynamicArrayValue return result } + + static getArc4TypeName = (_t: TypeInfo): string => { + return 'byte[]' + } } export class StaticBytesImpl extends StaticBytes { @@ -838,6 +871,11 @@ export class StaticBytesImpl extends StaticBytes { static getMaxBytesLength(typeInfo: TypeInfo): number { return StaticArrayImpl.getMaxBytesLength(typeInfo) } + + static getArc4TypeName = (t: TypeInfo): string => { + const genericArgs = t.genericArgs as StaticArrayGenericArgs + return `byte[${genericArgs.size.name}]` + } } const decode = (value: Uint8Array, childTypes: TypeInfo[]) => { @@ -1097,3 +1135,24 @@ export const getArc4Encoder = (typeInfo: TypeInfo, encoders?: Record } + +export const getArc4TypeName = (typeInfo: TypeInfo): string | undefined => { + const map = { + Address: 'address', + Bool: 'bool', + Byte: 'byte', + Str: 'string', + 'UintN<.*>': UintNImpl.getArc4TypeName, + 'UFixedNxM<.*>': UFixedNxMImpl.getArc4TypeName, + 'StaticArray<.*>': StaticArrayImpl.getArc4TypeName, + 'DynamicArray<.*>': DynamicArrayImpl.getArc4TypeName, + Tuple: TupleImpl.getArc4TypeName, + Struct: StructImpl.getArc4TypeName, + DynamicBytes: DynamicBytesImpl.getArc4TypeName, + 'StaticBytes<.*>': StaticBytesImpl.getArc4TypeName, + } + const name = Object.entries(map).find(([k, _]) => new RegExp(`^${k}$`, 'i').test(typeInfo.name))?.[1] + if (typeof name === 'string') return name + else if (typeof name === 'function') return name(typeInfo) + return undefined +} diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index f7d0a18..58b94ce 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -1,5 +1,6 @@ import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, LocalState } from '@algorandfoundation/algorand-typescript' -import { getAbiMetadata } from '../abi-metadata' +import { ABIMethod } from 'algosdk' +import { AbiMetadata, getAbiMetadata, getArc4Signature } from '../abi-metadata' import { BytesMap } from '../collections/custom-key-map' import { lazyContext } from '../context-helpers/internal-context' import type { TypeInfo } from '../encoders' @@ -69,7 +70,7 @@ const extractStates = (contract: BaseContract): States => { return states } -const extractArraysFromArgs = (app: Application, args: DeliberateAny[]) => { +const extractArraysFromArgs = (app: Application, methodSelector: Uint8Array, args: DeliberateAny[]) => { const transactions: Transaction[] = [] const accounts: Account[] = [] const apps: Application[] = [app] @@ -90,9 +91,7 @@ const extractArraysFromArgs = (app: Application, args: DeliberateAny[]) => { assets.push(arg as Asset) } } - - // TODO: use actual method selector in appArgs - return { accounts, apps, assets, transactions, appArgs: [Bytes('method_selector'), ...appArgs] } + return { accounts, apps, assets, transactions, appArgs: [Bytes(methodSelector), ...appArgs] } } function isTransaction(obj: unknown): obj is Transaction { @@ -112,14 +111,14 @@ export class ContractContext { return new proxy(...args) } - static createMethodCallTxns( + static createMethodCallTxns( contract: BaseContract, - method: (...args: TParams) => TReturn, + abiMetadata: AbiMetadata | undefined, ...args: TParams ): Transaction[] { - const abiMetadata = getAbiMetadata(contract, method.name) const app = lazyContext.ledger.getApplicationForContract(contract) - const { transactions, ...appCallArgs } = extractArraysFromArgs(app, args) + const methodSelector = abiMetadata ? ABIMethod.fromSignature(getArc4Signature(abiMetadata)).getSelector() : new Uint8Array() + const { transactions, ...appCallArgs } = extractArraysFromArgs(app, methodSelector, args) const appTxn = lazyContext.any.txn.applicationCall({ appId: app, ...appCallArgs, @@ -171,7 +170,7 @@ export class ContractContext { const isAbiMethod = isArc4 && abiMetadata if (isAbiMethod || isProgramMethod) { return (...args: DeliberateAny[]): DeliberateAny => { - const txns = ContractContext.createMethodCallTxns(receiver, orig as DeliberateAny, ...args) + const txns = ContractContext.createMethodCallTxns(receiver, abiMetadata, ...args) return lazyContext.txn.ensureScope(txns).execute(() => { const returnValue = (orig as DeliberateAny).apply(target, args) if (!isProgramMethod && isAbiMethod && returnValue !== undefined) { diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 56722ef..b0fd955 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -1,5 +1,6 @@ import { bytes, Contract, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' +import { getAbiMetadata } from '../abi-metadata' import { lazyContext } from '../context-helpers/internal-context' import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' import { testInvariant } from '../errors' @@ -130,7 +131,8 @@ export class TransactionContext { ...args: TParams ): DeferredAppCall { const appId = lazyContext.ledger.getApplicationForContract(contract) - const txns = ContractContext.createMethodCallTxns(contract, method, ...args) + const abiMetadata = getAbiMetadata(contract, method.name) + const txns = ContractContext.createMethodCallTxns(contract, abiMetadata, ...args) return new DeferredAppCall(appId.id, txns, method, args) } diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index f7f2577..49d5607 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -48,16 +48,21 @@ export const nodeFactory = { ) }, - attachMetaData(classIdentifier: ts.Identifier, method: ts.MethodDeclaration, functionType: ptypes.FunctionPType) { + attachMetaData( + classIdentifier: ts.Identifier, + method: ts.MethodDeclaration, + functionType: ptypes.FunctionPType, + argTypes: string[], + returnType: string, + ) { const methodName = getPropertyNameAsString(method.name) const metadata = factory.createObjectLiteralExpression([ factory.createPropertyAssignment('methodName', methodName), - factory.createPropertyAssignment('methodSelector', methodName), factory.createPropertyAssignment( 'argTypes', - factory.createArrayLiteralExpression(functionType.parameters.map((p) => factory.createStringLiteral(p[1].fullName))), + factory.createArrayLiteralExpression(argTypes.map((p) => factory.createStringLiteral(p))), ), - factory.createPropertyAssignment('returnType', factory.createStringLiteral(functionType.returnType.fullName)), + factory.createPropertyAssignment('returnType', factory.createStringLiteral(returnType)), ]) return factory.createExpressionStatement( factory.createCallExpression( diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index cba0798..76e5edf 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -249,7 +249,9 @@ class ClassVisitor { if (this.classDec.name && this.isArc4) { const methodType = this.helper.resolveType(node) if (methodType instanceof ptypes.FunctionPType) { - this.helper.additionalStatements.push(nodeFactory.attachMetaData(this.classDec.name, node, methodType)) + const argTypes = methodType.parameters.map((p) => JSON.stringify(getGenericTypeInfo(p[1]))) + const returnType = JSON.stringify(getGenericTypeInfo(methodType.returnType)) + this.helper.additionalStatements.push(nodeFactory.attachMetaData(this.classDec.name, node, methodType, argTypes, returnType)) } } @@ -318,7 +320,7 @@ const getGenericTypeInfo = (type: ptypes.PType): TypeInfo => { .map(([key, value]) => [key, getGenericTypeInfo(value)]) .filter((x) => !!x), ) - } else if (type instanceof ptypes.ARC4TupleType) { + } else if (type instanceof ptypes.ARC4TupleType || type instanceof ptypes.TuplePType) { genericArgs.push(...type.items.map(getGenericTypeInfo)) } diff --git a/tests/artifacts/created-app-asset/contract.algo.ts b/tests/artifacts/created-app-asset/contract.algo.ts index d532f13..6ec0344 100644 --- a/tests/artifacts/created-app-asset/contract.algo.ts +++ b/tests/artifacts/created-app-asset/contract.algo.ts @@ -1,4 +1,5 @@ -import { arc4, assert, Bytes, gtxn, op, uint64 } from '@algorandfoundation/algorand-typescript' +import { arc4, assert, Global, gtxn, op, uint64 } from '@algorandfoundation/algorand-typescript' +import { interpretAsArc4, methodSelector, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' export class AppExpectingEffects extends arc4.Contract { @arc4.abimethod() @@ -13,16 +14,8 @@ export class AppExpectingEffects extends arc4.Contract { @arc4.abimethod() public log_group(appCall: gtxn.ApplicationTxn): void { - assert(appCall.appArgs(0) === Bytes('some_value()uint64'), 'expected correct method called') + assert(appCall.appArgs(0) === methodSelector('some_value()uint64'), 'expected correct method called') assert(appCall.numLogs === 1, 'expected logs') - assert(appCall.lastLog === Bytes('this is a log statement')) + assert(interpretAsArc4(appCall.lastLog, 'log').native === (appCall.groupIndex + 1) * Global.groupSize) } - - // TODO: uncomment when arc4 stubs are implemented - // @arc4.abimethod() - // public log_group(appCall: gtxn.ApplicationTxn): void { - // assert(appCall.appArgs(0) === arc4.arc4Signature("some_value()uint64"), "expected correct method called") - // assert(appCall.numLogs === 1, "expected logs") - // assert(arc4.UInt64.from_log(appCall.lastLog) === (appCall.groupIndex + 1) * Global.groupSize) - // } } diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index cac8190..8bbeea6 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -2,10 +2,10 @@ import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import { ApplicationClient } 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 { DynamicBytes } from '@algorandfoundation/algorand-typescript/arc4' +import { DynamicBytes, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' -import { MIN_TXN_FEE, ZERO_ADDRESS } from '../src/constants' +import { ABI_RETURN_VALUE_LOG_PREFIX, MIN_TXN_FEE, ZERO_ADDRESS } from '../src/constants' import { testInvariant } from '../src/errors' import { Block, gloadBytes, gloadUint64 } from '../src/impl' import { AccountCls } from '../src/impl/account' @@ -285,22 +285,12 @@ describe('State op codes', async () => { it('should be able to pass app call txn as app arg', async () => { const appCallTxn = ctx.any.txn.applicationCall({ - appArgs: [Bytes('some_value()uint64')], - appLogs: [Bytes('this is a log statement')], + appArgs: [arc4.methodSelector('some_value()uint64')], + appLogs: [ABI_RETURN_VALUE_LOG_PREFIX.concat(new UintN64(2).bytes)], }) const contract = ctx.contract.create(AppExpectingEffects) contract.log_group(appCallTxn) }) - - // TODO: uncomment when arc4 stubs are implemented - // it('should be able to pass app call txn as app arg', async () => { - // const appCallTxn = ctx.any.txn.applicationCall({ - // appArgs: [arc4.arc4Signature("some_value()uint64")], - // logs: [arc4Prefix.concat(arc4.Uint64(2).bytes)] - // }) - // const contract = ctx.contract.create(AppExpectingEffects) - // contract.log_group(appCallTxn) - // }) }) describe('itxn', async () => { From b8da12d805d413e7ea984c29a264ffd1a5b46b1e Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 13 Dec 2024 17:32:02 +0800 Subject: [PATCH 67/85] fix: ensure contract proxy has abimetadata; fix: pass method name to deferAppCall; fix: add routing condition check; fix: capture state totals override from contract decorator --- examples/calculator/contract.spec.ts | 4 +- src/abi-metadata.ts | 23 ++++- src/context-helpers/context-util.ts | 21 +++++ src/context-helpers/internal-context.ts | 8 +- src/impl/inner-transactions.ts | 14 +-- src/impl/transactions.ts | 6 +- src/subcontexts/contract-context.ts | 63 +++++++++++-- src/subcontexts/transaction-context.ts | 32 +++++-- tests/references/arc4-contract.spec.ts | 117 ++++++++++++++++++++++++ tests/references/box.spec.ts | 4 +- 10 files changed, 259 insertions(+), 33 deletions(-) create mode 100644 src/context-helpers/context-util.ts create mode 100644 tests/references/arc4-contract.spec.ts diff --git a/examples/calculator/contract.spec.ts b/examples/calculator/contract.spec.ts index 4d5a122..61b1721 100644 --- a/examples/calculator/contract.spec.ts +++ b/examples/calculator/contract.spec.ts @@ -1,4 +1,4 @@ -import { internal, op, Uint64 } from '@algorandfoundation/algorand-typescript' +import { internal, Uint64 } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, expect, it } from 'vitest' import MyContract from './contract.algo' @@ -31,7 +31,7 @@ describe('Calculator', () => { .createScope([ ctx.any.txn.applicationCall({ appId: application, - appArgs: [op.itob(Uint64(1)), op.itob(Uint64(2)), op.itob(Uint64(3))], + appArgs: [Uint64(1), Uint64(2), Uint64(3)], }), ]) .execute(contract.approvalProgram) diff --git a/src/abi-metadata.ts b/src/abi-metadata.ts index be17f1a..57723a6 100644 --- a/src/abi-metadata.ts +++ b/src/abi-metadata.ts @@ -14,6 +14,7 @@ export interface AbiMetadata { allowActions?: OnCompleteActionStr[] } const AbiMetaSymbol = Symbol('AbiMetadata') +export const isContractProxy = Symbol('isContractProxy') export const attachAbiMetadata = (contract: { new (): Contract }, methodName: string, metadata: AbiMetadata): void => { const metadatas: Record = (AbiMetaSymbol in contract ? contract[AbiMetaSymbol] : {}) as Record metadatas[methodName] = metadata @@ -26,12 +27,21 @@ export const attachAbiMetadata = (contract: { new (): Contract }, methodName: st } } +export const copyAbiMetadatas = (sourceContract: T, targetContract: T): void => { + const metadatas = getContractAbiMetadata(sourceContract) + Object.defineProperty(targetContract, AbiMetaSymbol, { + value: metadatas, + writable: true, + enumerable: false, + }) +} + export const captureMethodConfig = ( contract: T, methodName: string, config?: AbiMethodConfig | BareMethodConfig, ): void => { - const metadata = getAbiMetadata(contract, methodName) + const metadata = getContractMethodAbiMetadata(contract, methodName) metadata.onCreate = config?.onCreate ?? 'disallow' metadata.allowActions = ([] as OnCompleteActionStr[]).concat(config?.allowActions ?? 'NoOp') } @@ -42,13 +52,20 @@ export const hasAbiMetadata = (contract: T): boolean => { Object.getOwnPropertySymbols(contractClass).some((s) => s.toString() === AbiMetaSymbol.toString()) || AbiMetaSymbol in contractClass ) } - -export const getAbiMetadata = (contract: T, methodName: string): AbiMetadata => { +export const getContractAbiMetadata = (contract: T): Record => { + if ((contract as DeliberateAny)[isContractProxy]) { + return (contract as DeliberateAny)[AbiMetaSymbol] as Record + } 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 +} + +export const getContractMethodAbiMetadata = (contract: T, methodName: string): AbiMetadata => { + const metadatas = getContractAbiMetadata(contract) return metadatas[methodName] } diff --git a/src/context-helpers/context-util.ts b/src/context-helpers/context-util.ts new file mode 100644 index 0000000..7cfb006 --- /dev/null +++ b/src/context-helpers/context-util.ts @@ -0,0 +1,21 @@ +import { internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { AbiMetadata } from '../abi-metadata' +import { ApplicationTransaction } from '../impl/transactions' +import { lazyContext } from './internal-context' + +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') + } + if (!isCreating && metadata.onCreate === 'require') { + throw new internal.errors.CodeError('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(', ')}`, + ) + } +} diff --git a/src/context-helpers/internal-context.ts b/src/context-helpers/internal-context.ts index 459e995..e7b6e1d 100644 --- a/src/context-helpers/internal-context.ts +++ b/src/context-helpers/internal-context.ts @@ -1,4 +1,4 @@ -import { Account, internal } from '@algorandfoundation/algorand-typescript' +import { Account, BaseContract, internal } from '@algorandfoundation/algorand-typescript' import { AccountData } from '../impl/account' import { ApplicationData } from '../impl/application' import { AssetData } from '../impl/asset' @@ -60,8 +60,10 @@ class InternalContext { return data } - getApplicationData(id: internal.primitives.StubUint64Compat): ApplicationData { - const data = this.ledger.applicationDataMap.get(id) + getApplicationData(id: internal.primitives.StubUint64Compat | BaseContract): ApplicationData { + const uint64Id = + id instanceof BaseContract ? this.ledger.getApplicationForContract(id).id : internal.primitives.Uint64Cls.fromCompat(id) + const data = this.ledger.applicationDataMap.get(uint64Id) if (!data) { throw internal.errors.internalError('Unknown application, check correct testing context is active') } diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts index 8f6c4ea..ea68185 100644 --- a/src/impl/inner-transactions.ts +++ b/src/impl/inner-transactions.ts @@ -1,4 +1,10 @@ import { Account, Application, arc4, Asset, bytes, internal, itxn, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' +import { Mutable } from '../typescript-helpers' +import { asBytes } from '../util' +import { getApp } from './app-params' +import { getAsset } from './asset-params' +import { InnerTxn, InnerTxnFields } from './itxn' import { ApplicationTransaction, AssetConfigTransaction, @@ -7,12 +13,6 @@ import { KeyRegistrationTransaction, PaymentTransaction, } from './transactions' -import { asBytes, toBytes } from '../util' -import { getAsset } from './asset-params' -import { InnerTxn, InnerTxnFields } from './itxn' -import { getApp } from './app-params' -import { Mutable } from '../typescript-helpers' -import { lazyContext } from '../context-helpers/internal-context' const mapCommonFields = ( fields: T, @@ -149,7 +149,7 @@ export class ApplicationInnerTxn extends ApplicationTransaction implements itxn. approvalProgramPages: Array.isArray(approvalProgram) ? approvalProgram : undefined, clearStateProgram: Array.isArray(clearStateProgram) ? undefined : (clearStateProgram as bytes), clearStateProgramPages: Array.isArray(clearStateProgram) ? clearStateProgram : undefined, - appArgs: appArgs?.map((x) => toBytes(x)), + appArgs: appArgs?.map((x) => x), accounts: accounts?.map((x) => x), assets: assets?.map((x) => x), apps: apps?.map((x) => x), diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index d6fae1a..6e0b85e 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -226,7 +226,7 @@ export class AssetFreezeTransaction extends TransactionBase implements gtxn.Asse export type ApplicationTransactionFields = TxnFields & Partial<{ - appArgs: Array + appArgs: Array accounts: Array assets: Array apps: Array @@ -241,7 +241,7 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl static create(fields: ApplicationTransactionFields) { return new ApplicationTransaction(fields) } - #appArgs: Array + #appArgs: Array #accounts: Array #assets: Array #apps: Array @@ -308,7 +308,7 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl return this.#appLogs.at(-1) ?? lazyContext.getApplicationData(this.appId.id).appLogs.at(-1) ?? Bytes() } appArgs(index: internal.primitives.StubUint64Compat): bytes { - return this.#appArgs[asNumber(index)] + return toBytes(this.#appArgs[asNumber(index)]) } accounts(index: internal.primitives.StubUint64Compat): Account { return this.#accounts[asNumber(index)] diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 58b94ce..26b7d62 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -1,7 +1,26 @@ -import { Account, Application, Asset, BaseContract, Bytes, bytes, Contract, LocalState } from '@algorandfoundation/algorand-typescript' +import { + Account, + Application, + Asset, + BaseContract, + Bytes, + bytes, + Contract, + contract, + internal, + LocalState, +} from '@algorandfoundation/algorand-typescript' import { ABIMethod } from 'algosdk' -import { AbiMetadata, getAbiMetadata, getArc4Signature } from '../abi-metadata' +import { + AbiMetadata, + copyAbiMetadatas, + getArc4Signature, + getContractAbiMetadata, + getContractMethodAbiMetadata, + isContractProxy, +} 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 type { TypeInfo } from '../encoders' import { AccountCls } from '../impl/account' @@ -21,6 +40,8 @@ import { getGenericTypeInfo } from '../runtime-helpers' import { DeliberateAny, IConstructor } from '../typescript-helpers' import { toBytes } from '../util' +type ContractOptionsParameter = Parameters[0] + type StateTotals = Pick interface States { @@ -34,7 +55,7 @@ const isUint64GenericType = (typeInfo: TypeInfo | undefined) => { return typeInfo.genericArgs.some((t) => t.name.toLocaleLowerCase() === 'uint64') } -const extractStates = (contract: BaseContract): States => { +const extractStates = (contract: BaseContract, contractOptions: ContractOptionsParameter | undefined): States => { const stateTotals = { globalNumBytes: 0, globalNumUint: 0, localNumBytes: 0, localNumUint: 0 } const states = { globalStates: new BytesMap>(), @@ -67,6 +88,12 @@ const extractStates = (contract: BaseContract): States => { stateTotals.localNumBytes += isLocalState && !isUint64State ? 1 : 0 } }) + + stateTotals.globalNumUint = contractOptions?.stateTotals?.globalUints ?? stateTotals.globalNumUint + stateTotals.globalNumBytes = contractOptions?.stateTotals?.globalBytes ?? stateTotals.globalNumBytes + stateTotals.localNumUint = contractOptions?.stateTotals?.localUints ?? stateTotals.localNumUint + stateTotals.localNumBytes = contractOptions?.stateTotals?.localBytes ?? stateTotals.localNumBytes + return states } @@ -142,8 +169,8 @@ export class ContractContext { } private getContractProxyHandler(isArc4: boolean): ProxyHandler> { - const onConstructed = (application: Application, instance: T) => { - const states = extractStates(instance) + const onConstructed = (application: Application, instance: T, conrtactOptions: ContractOptionsParameter | undefined) => { + const states = extractStates(instance, conrtactOptions) const applicationData = lazyContext.ledger.applicationDataMap.getOrFail(application.id) applicationData.application = { @@ -159,23 +186,33 @@ export class ContractContext { let t: T | undefined = undefined const application = lazyContext.any.application() const txn = lazyContext.any.txn.applicationCall({ appId: application }) + const appData = lazyContext.ledger.applicationDataMap.getOrFail(application.id) + appData.isCreating = true lazyContext.txn.ensureScope([txn]).execute(() => { t = new target(...args) }) + appData.isCreating = hasCreateMethods(t!) const instance = new Proxy(t!, { get(target, prop, receiver) { + if (prop === isContractProxy) { + return true + } const orig = Reflect.get(target, prop, receiver) - const abiMetadata = getAbiMetadata(target, prop as string) + const abiMetadata = getContractMethodAbiMetadata(target, prop as string) const isProgramMethod = prop === 'approvalProgram' || prop === 'clearStateProgram' const isAbiMethod = isArc4 && abiMetadata if (isAbiMethod || isProgramMethod) { return (...args: DeliberateAny[]): DeliberateAny => { const txns = ContractContext.createMethodCallTxns(receiver, abiMetadata, ...args) return lazyContext.txn.ensureScope(txns).execute(() => { + if (isAbiMethod) { + checkRoutingConditions(application.id, abiMetadata) + } const returnValue = (orig as DeliberateAny).apply(target, args) if (!isProgramMethod && isAbiMethod && returnValue !== undefined) { ;(txns.at(-1) as ApplicationTransaction).logArc4ReturnValue(returnValue) } + appData.isCreating = false return returnValue }) } @@ -184,10 +221,22 @@ export class ContractContext { }, }) - onConstructed(application, instance) + onConstructed(application, instance, getContractOptions(t!)) + + copyAbiMetadatas(t!, instance) return instance }, } } } + +const getContractOptions = (contract: BaseContract): ContractOptionsParameter | undefined => { + const contractClass = contract.constructor as DeliberateAny + return contractClass[internal.ContractOptionsSymbol] as ContractOptionsParameter +} + +const hasCreateMethods = (contract: BaseContract) => { + const metadatas = getContractAbiMetadata(contract) + return Object.values(metadatas).some((metadata) => (metadata.onCreate ?? 'disallow') !== 'disallow') +} diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index b0fd955..dacd212 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -1,6 +1,6 @@ import { bytes, Contract, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' import algosdk from 'algosdk' -import { getAbiMetadata } from '../abi-metadata' +import { AbiMetadata, getContractMethodAbiMetadata } from '../abi-metadata' import { lazyContext } from '../context-helpers/internal-context' import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' import { testInvariant } from '../errors' @@ -24,6 +24,7 @@ import { PaymentTransaction, Transaction, } from '../impl/transactions' +import { FunctionKeys } from '../typescript-helpers' import { asBigInt, asNumber, asUint64 } from '../util' import { ContractContext } from './contract-context' @@ -48,16 +49,34 @@ interface ExecutionScope { execute: (body: () => TReturn) => TReturn } +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') + } + if (!isCreating && metadata.onCreate === 'require') { + throw new internal.errors.CodeError('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(', ')}`, + ) + } +} + export class DeferredAppCall { constructor( private readonly appId: uint64, readonly txns: Transaction[], private readonly method: (...args: TParams) => TReturn, + private readonly abiMetadata: AbiMetadata, private readonly args: TParams, ) {} submit(): TReturn { - // TODO: check_routing_conditions + checkRoutingConditions(this.appId, this.abiMetadata) return this.method(...this.args) } } @@ -125,15 +144,16 @@ export class TransactionContext { activeTransaction.appendLog(value) } - deferAppCall( - contract: Contract, + deferAppCall( + contract: TContract, method: (...args: TParams) => TReturn, + methodName: FunctionKeys, ...args: TParams ): DeferredAppCall { const appId = lazyContext.ledger.getApplicationForContract(contract) - const abiMetadata = getAbiMetadata(contract, method.name) + const abiMetadata = getContractMethodAbiMetadata(contract, methodName as string) const txns = ContractContext.createMethodCallTxns(contract, abiMetadata, ...args) - return new DeferredAppCall(appId.id, txns, method, args) + return new DeferredAppCall(appId.id, txns, method, abiMetadata, args) } exportLogs(appId: uint64, ...decoding: T): DecodedLogs { diff --git a/tests/references/arc4-contract.spec.ts b/tests/references/arc4-contract.spec.ts new file mode 100644 index 0000000..13b5c67 --- /dev/null +++ b/tests/references/arc4-contract.spec.ts @@ -0,0 +1,117 @@ +import { + Account, + arc4, + assert, + BaseContract, + bytes, + Bytes, + contract, + Contract, + Global, + Txn, + uint64, + 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' + +class ContractTxnInit extends BaseContract { + arg1: bytes + creator: Account + + constructor() { + super() + this.arg1 = Txn.numAppArgs > 0 ? Txn.applicationArgs(0) : Bytes() + this.creator = Txn.sender + } + + approvalProgram(): boolean { + return true + } + + clearStateProgram(): boolean { + return true + } +} + +@contract({ stateTotals: { globalBytes: 4, globalUints: 5, localBytes: 6, localUints: 7 } }) +class ContractARC4Create extends Contract { + creator: Account + #name: string + #scratchSlots: uint64 + #stateTotals: uint64 + arg1: uint64 | undefined + + constructor() { + super() + this.creator = Txn.sender + this.#name = 'name' + this.#scratchSlots = Uint64() + this.#stateTotals = Uint64() + } + + @arc4.abimethod({ onCreate: 'require' }) + create(val: uint64): void { + this.arg1 = val + assert(Global.currentApplicationId.globalNumBytes === 4) + assert(Global.currentApplicationId.globalNumUint === 5) + assert(Global.currentApplicationId.localNumBytes === 6) + assert(Global.currentApplicationId.localNumUint === 7) + assert(this.#name === 'name') + assert(this.#scratchSlots === 0) + assert(this.#stateTotals === 0) + } +} + +describe('arc4 contract creation', () => { + const ctx = new TestExecutionContext() + + afterEach(() => { + ctx.reset() + }) + + it('can create contract with txn in init', () => { + const arg1 = ctx.any.bytes(5) + const sender = ctx.any.account() + + ctx.txn.createScope([ctx.any.txn.applicationCall({ appArgs: [arg1], sender })]).execute(() => { + const contract = ctx.contract.create(ContractTxnInit) + expect(contract.arg1).toEqual(arg1) + expect(contract.creator).toEqual(sender) + }) + }) + + it('can create contract without txn in init', () => { + const contract = ctx.contract.create(ContractTxnInit) + expect(contract.arg1).toEqual(Bytes()) + expect(contract.creator).toEqual(ctx.defaultSender) + }) + + it('can create arc4 contract with txn in init', () => { + const arg1 = ctx.any.uint64() + const sender = ctx.any.account() + + const contract = ctx.contract.create(ContractARC4Create) + ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: ctx.ledger.getApplicationForContract(contract), sender })]).execute(() => { + contract.create(arg1) + expect(contract.arg1).toEqual(arg1) + expect(contract.creator).toEqual(sender) + }) + }) + + it('can create arc4 contract without txn in init', () => { + const arg1 = ctx.any.uint64() + + const contract = ctx.contract.create(ContractARC4Create) + + const appData = lazyContext.getApplicationData(contract) + expect(appData.isCreating).toBe(true) + + contract.create(arg1) + + expect(appData.isCreating).toBe(false) + expect(contract.arg1).toEqual(arg1) + expect(contract.creator).toEqual(ctx.defaultSender) + }) +}) diff --git a/tests/references/box.spec.ts b/tests/references/box.spec.ts index e68d5af..c64894a 100644 --- a/tests/references/box.spec.ts +++ b/tests/references/box.spec.ts @@ -169,8 +169,8 @@ describe('Box', () => { it('can store enum values', () => { const contract = ctx.contract.create(BoxContract) - const deferredStoreCall = ctx.txn.deferAppCall(contract, contract.storeEnums) - const deferredReadCall = ctx.txn.deferAppCall(contract, contract.read_enums) + const deferredStoreCall = ctx.txn.deferAppCall(contract, contract.storeEnums, 'storeEnums') + const deferredReadCall = ctx.txn.deferAppCall(contract, contract.read_enums, 'read_enums') ctx.txn.createScope([deferredStoreCall, deferredReadCall]).execute(() => { deferredStoreCall.submit() From f393ae875c6fadf16e01b6b26f7d0510694e6331 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 17 Dec 2024 18:00:12 +0800 Subject: [PATCH 68/85] chore: update typescript to match algots and puyats packages --- package-lock.json | 8 +++---- package.json | 2 +- ...ipt+5.6.2.patch => typescript+5.7.2.patch} | 22 +++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) rename patches/{typescript+5.6.2.patch => typescript+5.7.2.patch} (69%) diff --git a/package-lock.json b/package-lock.json index 6e814a4..a4c279c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "rollup": "^4.24.0", "semantic-release": "^24.1.2", "tsx": "4.19.1", - "typescript": "5.6.2", + "typescript": "^5.7.2", "vitest": "2.1.2" }, "peerDependencies": { @@ -12945,9 +12945,9 @@ } }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index eb6421d..1aa88c1 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "rollup": "^4.24.0", "semantic-release": "^24.1.2", "tsx": "4.19.1", - "typescript": "5.6.2", + "typescript": "^5.7.2", "vitest": "2.1.2" }, "peerDependencies": { diff --git a/patches/typescript+5.6.2.patch b/patches/typescript+5.7.2.patch similarity index 69% rename from patches/typescript+5.6.2.patch rename to patches/typescript+5.7.2.patch index 9712991..f28cd8b 100644 --- a/patches/typescript+5.6.2.patch +++ b/patches/typescript+5.7.2.patch @@ -1,20 +1,20 @@ diff --git a/node_modules/typescript/lib/typescript.d.ts b/node_modules/typescript/lib/typescript.d.ts -index 963c573..299a8a4 100644 +index 6780dd1..8700e72 100644 --- a/node_modules/typescript/lib/typescript.d.ts +++ b/node_modules/typescript/lib/typescript.d.ts -@@ -6116,6 +6116,7 @@ declare namespace ts { +@@ -6159,6 +6159,7 @@ declare namespace ts { getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; getIndexInfosOfType(type: Type): readonly IndexInfo[]; - getIndexInfosOfIndexSymbol: (indexSymbol: Symbol) => 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 90f3266..9daa319 100644 +index 33387ea..a1f35b3 100644 --- a/node_modules/typescript/lib/typescript.js +++ b/node_modules/typescript/lib/typescript.js -@@ -50171,6 +50171,7 @@ function createTypeChecker(host) { +@@ -50655,6 +50655,7 @@ function createTypeChecker(host) { getGlobalDiagnostics, getRecursionIdentity, getUnmatchedProperties, @@ -22,13 +22,13 @@ index 90f3266..9daa319 100644 getTypeOfSymbolAtLocation: (symbol, locationIn) => { const location = getParseTreeNode(locationIn); return location ? getTypeOfSymbolAtLocation(symbol, location) : errorType; -@@ -92895,6 +92896,9 @@ function createTypeChecker(host) { - Debug.assert(specifier && nodeIsSynthesized(specifier) && specifier.text === "tslib", `Expected sourceFile.imports[0] to be the synthesized tslib import`); - return specifier; +@@ -71776,6 +71777,9 @@ function createTypeChecker(host) { + } + } } + function getTypeArgumentsForResolvedSignature(signature) { + return signature.mapper && instantiateTypes((signature.target ?? signature).typeParameters ?? [], signature.mapper); + } - } - function isNotAccessor(declaration) { - return !isAccessor(declaration); + function getUnmatchedProperty(source, target, requireOptionalProperties, matchDiscriminantProperties) { + return firstOrUndefinedIterator(getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties)); + } From f01f372c9f927a9eb7afc02c6352876a2aba9c43 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Wed, 18 Dec 2024 11:20:26 +0800 Subject: [PATCH 69/85] chore: upgrade puya-ts and algots package versions --- package-lock.json | 21 ++++++++++----------- package.json | 4 ++-- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index a4c279c..4c98251 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,8 @@ "hasInstallScript": true, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.20", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.32", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.22", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.34", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", @@ -73,17 +73,17 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.20", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.20.tgz", - "integrity": "sha512-XpIxvfOQdcZV1cG4TI6pXDtvYDtReWX6xW4bEuVn9FSpVrg1Vgs0lW03QoLK1sNs38Y/oW1UV9iep1P1AJX6fA==", + "version": "0.0.1-alpha.22", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.22.tgz", + "integrity": "sha512-RhPxX2wU3srIEmA8EgjEbE8lJQqJrUW78aKS2VnpVS/uejHMDDt+kQIjtjpNEB+vxli8shaBYZ8TM0h1wE5b0g==", "peerDependencies": { "tslib": "^2.6.2" } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0-alpha.32", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.32.tgz", - "integrity": "sha512-9mMS8v9AksNDS9rVy+KJmbUjtYvOmXQh8ThNZ+yyvFct+vhEdiBTBnoaUsOXsTjpMtchh1GHUkjjtVKhHUuRsg==", + "version": "1.0.0-alpha.34", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.34.tgz", + "integrity": "sha512-H5MHNk6JDV5NeWlV9na+MZvN2Jge/PcVhINOCHNG4RixYU/rBPBzbpIvpbQkSjo7uWrqaxFSHUtL08H+/cLClg==", "bundleDependencies": [ "typescript" ], @@ -95,7 +95,7 @@ "cross-spawn": "7.0.6", "glob": "^11.0.0", "polytype": "^0.17.0", - "typescript": "5.6.2", + "typescript": "^5.7.2", "upath": "^2.0.1", "zod": "^3.24.0" }, @@ -105,7 +105,7 @@ } }, "node_modules/@algorandfoundation/puya-ts/node_modules/typescript": { - "version": "5.6.2", + "version": "5.7.2", "inBundle": true, "license": "Apache-2.0", "bin": { @@ -12948,7 +12948,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", - "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 1aa88c1..b2d7492 100644 --- a/package.json +++ b/package.json @@ -63,8 +63,8 @@ }, "dependencies": { "@algorandfoundation/algokit-utils": "^6.2.1", - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.20", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.32", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.22", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.34", "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", From cbbc86a822a73d7ecfec3d67dfd55e39f2e52153 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 20 Dec 2024 18:15:56 +0800 Subject: [PATCH 70/85] refactor: remove dependency on algosdk, move algokit-utils to dev dependency and upgrade algokit-util to 8.0.3 --- package-lock.json | 1366 +++++++++++------ package.json | 3 +- src/abi-metadata.ts | 10 +- src/constants.ts | 19 + src/impl/application.ts | 8 +- src/impl/crypto.ts | 11 +- src/impl/encoded-types.ts | 11 +- src/impl/global.ts | 9 +- src/subcontexts/contract-context.ts | 5 +- src/subcontexts/transaction-context.ts | 12 +- src/test-execution-context.ts | 6 +- src/util.ts | 39 +- src/value-generators/avm.ts | 5 +- tests/arc4/address.spec.ts | 15 +- tests/arc4/dynamic-array.spec.ts | 52 +- tests/arc4/dynamic-bytes.spec.ts | 10 +- tests/arc4/static-array.spec.ts | 48 +- tests/arc4/static-bytes.spec.ts | 14 +- tests/arc4/struct.spec.ts | 25 +- tests/arc4/tuple.spec.ts | 30 +- tests/arc4/uintn.spec.ts | 6 +- .../data/CryptoOpsContract.arc56.json | 467 ++++++ tests/avm-invoker.ts | 140 +- tests/crypto-op-codes.spec.ts | 35 +- tests/global-state-arc4-values.spec.ts | 2 +- tests/local-state-arc4-values.spec.ts | 11 +- tests/state-op-codes.spec.ts | 94 +- tests/util.ts | 2 +- 28 files changed, 1684 insertions(+), 771 deletions(-) create mode 100644 tests/artifacts/crypto-ops/data/CryptoOpsContract.arc56.json diff --git a/package-lock.json b/package-lock.json index 4c98251..b96dcaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,8 @@ "version": "1.0.0", "hasInstallScript": true, "dependencies": { - "@algorandfoundation/algokit-utils": "^6.2.1", "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.22", "@algorandfoundation/puya-ts": "^1.0.0-alpha.34", - "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", @@ -20,6 +18,7 @@ "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", @@ -58,18 +57,19 @@ } }, "node_modules/@algorandfoundation/algokit-utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-utils/-/algokit-utils-6.2.1.tgz", - "integrity": "sha512-oJbqT91KJp34OasYID2guWHysCLdgZ/4GVb06sdgXxORWKKMhZa/Uj12UiACo4VzZJBOUZEJCh/QrSuHmu/m2g==", + "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==", + "dev": true, "license": "MIT", "dependencies": { "buffer": "^6.0.3" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { - "algosdk": "^2.7.0" + "algosdk": "^3.0.0" } }, "node_modules/@algorandfoundation/algorand-typescript": { @@ -81,9 +81,9 @@ } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0-alpha.34", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.34.tgz", - "integrity": "sha512-H5MHNk6JDV5NeWlV9na+MZvN2Jge/PcVhINOCHNG4RixYU/rBPBzbpIvpbQkSjo7uWrqaxFSHUtL08H+/cLClg==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-beta.2.tgz", + "integrity": "sha512-kHIWCOmsU18ceLMKrzTa6Q4hfHp7+Ai58rcxdqNNKtDfzvffWuPLI6oMP2gj6wP+ZTrIdoLNGMhJVOlvtCYpew==", "bundleDependencies": [ "typescript" ], @@ -166,13 +166,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.0" + "@babel/types": "^7.26.3" }, "bin": { "parser": "bin/babel-parser.js" @@ -182,9 +182,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", "dev": true, "license": "MIT", "dependencies": { @@ -214,15 +214,15 @@ } }, "node_modules/@commitlint/cli": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.5.0.tgz", - "integrity": "sha512-gaGqSliGwB86MDmAAKAtV9SV1SHdmN8pnGq4EJU4+hLisQ7IFfx4jvU4s+pk6tl0+9bv6yT+CaZkufOinkSJIQ==", + "version": "19.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.6.1.tgz", + "integrity": "sha512-8hcyA6ZoHwWXC76BoC8qVOSr8xHy00LZhZpauiD0iO0VYbVhMnED0da85lTfIULxl7Lj4c6vZgF0Wu/ed1+jlQ==", "dev": true, "license": "MIT", "dependencies": { "@commitlint/format": "^19.5.0", - "@commitlint/lint": "^19.5.0", - "@commitlint/load": "^19.5.0", + "@commitlint/lint": "^19.6.0", + "@commitlint/load": "^19.6.1", "@commitlint/read": "^19.5.0", "@commitlint/types": "^19.5.0", "tinyexec": "^0.3.0", @@ -236,9 +236,9 @@ } }, "node_modules/@commitlint/config-conventional": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.5.0.tgz", - "integrity": "sha512-OBhdtJyHNPryZKg0fFpZNOBM1ZDbntMvqMuSmpfyP86XSfwzGw4CaoYRG4RutUPg0BTK07VMRIkNJT6wi2zthg==", + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.6.0.tgz", + "integrity": "sha512-DJT40iMnTYtBtUfw9ApbsLZFke1zKh6llITVJ+x9mtpHD08gsNXaIRqHTmwTZL3dNX5+WoyK7pCN/5zswvkBCQ==", "dev": true, "license": "MIT", "dependencies": { @@ -319,9 +319,9 @@ } }, "node_modules/@commitlint/is-ignored": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.5.0.tgz", - "integrity": "sha512-0XQ7Llsf9iL/ANtwyZ6G0NGp5Y3EQ8eDQSxv/SRcfJ0awlBY4tHFAvwWbw66FVUaWICH7iE5en+FD9TQsokZ5w==", + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.6.0.tgz", + "integrity": "sha512-Ov6iBgxJQFR9koOupDPHvcHU9keFupDgtB3lObdEZDroiG4jj1rzky60fbQozFKVYRTUdrBGICHG0YVmRuAJmw==", "dev": true, "license": "MIT", "dependencies": { @@ -333,15 +333,15 @@ } }, "node_modules/@commitlint/lint": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.5.0.tgz", - "integrity": "sha512-cAAQwJcRtiBxQWO0eprrAbOurtJz8U6MgYqLz+p9kLElirzSCc0vGMcyCaA1O7AqBuxo11l1XsY3FhOFowLAAg==", + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.6.0.tgz", + "integrity": "sha512-LRo7zDkXtcIrpco9RnfhOKeg8PAnE3oDDoalnrVU/EVaKHYBWYL1DlRR7+3AWn0JiBqD8yKOfetVxJGdEtZ0tg==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/is-ignored": "^19.5.0", + "@commitlint/is-ignored": "^19.6.0", "@commitlint/parse": "^19.5.0", - "@commitlint/rules": "^19.5.0", + "@commitlint/rules": "^19.6.0", "@commitlint/types": "^19.5.0" }, "engines": { @@ -349,9 +349,9 @@ } }, "node_modules/@commitlint/load": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.5.0.tgz", - "integrity": "sha512-INOUhkL/qaKqwcTUvCE8iIUf5XHsEPCLY9looJ/ipzi7jtGhgmtH7OOFiNvwYgH7mA8osUWOUDV8t4E2HAi4xA==", + "version": "19.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.6.1.tgz", + "integrity": "sha512-kE4mRKWWNju2QpsCWt428XBvUH55OET2N4QKQ0bF85qS/XbsRGG1MiTByDNlEVpEPceMkDr46LNH95DtRwcsfA==", "dev": true, "license": "MIT", "dependencies": { @@ -361,7 +361,7 @@ "@commitlint/types": "^19.5.0", "chalk": "^5.3.0", "cosmiconfig": "^9.0.0", - "cosmiconfig-typescript-loader": "^5.0.0", + "cosmiconfig-typescript-loader": "^6.1.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "lodash.uniq": "^4.5.0" @@ -431,9 +431,9 @@ } }, "node_modules/@commitlint/rules": { - "version": "19.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.5.0.tgz", - "integrity": "sha512-hDW5TPyf/h1/EufSHEKSp6Hs+YVsDMHazfJ2azIk9tHPXS6UqSz1dIRs1gpqS3eMXgtkT7JH6TW4IShdqOwhAw==", + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.6.0.tgz", + "integrity": "sha512-1f2reW7lbrI0X0ozZMesS/WZxgPa4/wi56vFuJENBmed6mWq5KsheN/nxqnl/C23ioxpPO/PL6tXpiiFy5Bhjw==", "dev": true, "license": "MIT", "dependencies": { @@ -1004,9 +1004,9 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1106,9 +1106,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, "license": "MIT", "dependencies": { @@ -1349,13 +1349,13 @@ "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "11.3.5", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.5.tgz", - "integrity": "sha512-cgwIRtKrpwhLoBi0CUNuY83DPGRMaWVjqVI/bGKsLJ4PzyWZNaEmhHroI2xlrVXkk6nFv0IsZpOp+ZWSWUS2AQ==", + "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==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^13.6.0" + "@octokit/types": "^13.6.2" }, "engines": { "node": ">= 18" @@ -1429,9 +1429,9 @@ } }, "node_modules/@octokit/types": { - "version": "13.6.1", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", - "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "version": "13.6.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.2.tgz", + "integrity": "sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==", "dev": true, "license": "MIT", "dependencies": { @@ -1594,9 +1594,9 @@ } }, "node_modules/@rollup/plugin-typescript": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.1.tgz", - "integrity": "sha512-t7O653DpfB5MbFrqPe/VcKFFkvRuFNp9qId3xq4Eth5xlyymzxNpye2z8Hrl0RIMuXTSr5GGcFpkdlMeacUiFQ==", + "version": "12.1.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.2.tgz", + "integrity": "sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg==", "dev": true, "license": "MIT", "dependencies": { @@ -1621,9 +1621,9 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", - "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1644,9 +1644,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz", - "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", + "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==", "cpu": [ "arm" ], @@ -1658,9 +1658,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz", - "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz", + "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==", "cpu": [ "arm64" ], @@ -1672,9 +1672,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz", - "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz", + "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==", "cpu": [ "arm64" ], @@ -1686,9 +1686,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz", - "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz", + "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==", "cpu": [ "x64" ], @@ -1700,9 +1700,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz", - "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz", + "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==", "cpu": [ "arm64" ], @@ -1714,9 +1714,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz", - "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz", + "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==", "cpu": [ "x64" ], @@ -1728,9 +1728,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz", - "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz", + "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==", "cpu": [ "arm" ], @@ -1742,9 +1742,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz", - "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz", + "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==", "cpu": [ "arm" ], @@ -1756,9 +1756,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz", - "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz", + "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==", "cpu": [ "arm64" ], @@ -1770,9 +1770,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz", - "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz", + "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==", "cpu": [ "arm64" ], @@ -1783,10 +1783,24 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz", + "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz", - "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz", + "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==", "cpu": [ "ppc64" ], @@ -1798,9 +1812,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz", - "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz", + "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==", "cpu": [ "riscv64" ], @@ -1812,9 +1826,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz", - "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz", + "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==", "cpu": [ "s390x" ], @@ -1826,9 +1840,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz", - "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz", + "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==", "cpu": [ "x64" ], @@ -1840,9 +1854,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz", - "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz", + "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==", "cpu": [ "x64" ], @@ -1854,9 +1868,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz", - "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz", + "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==", "cpu": [ "arm64" ], @@ -1868,9 +1882,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz", - "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz", + "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==", "cpu": [ "ia32" ], @@ -1882,9 +1896,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz", - "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz", + "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==", "cpu": [ "x64" ], @@ -1978,9 +1992,9 @@ } }, "node_modules/@semantic-release/github": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-11.0.0.tgz", - "integrity": "sha512-Uon6G6gJD8U1JNvPm7X0j46yxNRJ8Ui6SgK4Zw5Ktu8RgjEft3BGn+l/RX1TTzhhO3/uUcKuqM+/9/ETFxWS/Q==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-11.0.1.tgz", + "integrity": "sha512-Z9cr0LgU/zgucbT9cksH0/pX9zmVda9hkDPcgIE0uvjMQ8w/mElDivGjx1w1pEQ+MuQJ5CBq3VCF16S6G4VH3A==", "dev": true, "license": "MIT", "dependencies": { @@ -2125,9 +2139,9 @@ } }, "node_modules/@semantic-release/release-notes-generator": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.0.1.tgz", - "integrity": "sha512-K0w+5220TM4HZTthE5dDpIuFrnkN1NfTGPidJFm04ULT1DEZ9WG89VNXN7F0c+6nMEpWgqmPvb7vY7JkB2jyyA==", + "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==", "dev": true, "license": "MIT", "dependencies": { @@ -2248,9 +2262,9 @@ } }, "node_modules/@types/conventional-commits-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", - "integrity": "sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz", + "integrity": "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2616,9 +2630,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.4.tgz", - "integrity": "sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", + "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2742,14 +2756,11 @@ } }, "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "dev": true, "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, "engines": { "node": ">= 14" } @@ -2788,23 +2799,26 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/algo-msgpack-with-bigint": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", - "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==", + "node_modules/algorand-msgpack": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/algorand-msgpack/-/algorand-msgpack-1.1.0.tgz", + "integrity": "sha512-08k7pBQnkaUB5p+jL7f1TRaUIlTSDE0cesFu1mD7llLao+1cAhtvvZmGE3OnisTd0xOn118QMw74SRqddqaYvw==", + "dev": true, "license": "ISC", + "peer": true, "engines": { - "node": ">= 10" + "node": ">= 14" } }, "node_modules/algosdk": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-2.9.0.tgz", - "integrity": "sha512-o0n0nLMbTX6SFQdMUk2/2sy50jmEmZk5OTPYSh2aAeP8DUPxrhjMPfwGsYNvaO+qk75MixC2eWpfA9vygCQ/Mg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-3.0.0.tgz", + "integrity": "sha512-PIKZ/YvbBpCudduug4KSH1CY/pTotI7/ccbUIbXKtcI9Onevl+57E+K5X4ow4gsCdysZ8zVvSLdxuCcXvsmPOw==", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "algo-msgpack-with-bigint": "^2.1.1", - "buffer": "^6.0.3", + "algorand-msgpack": "^1.1.0", "hi-base32": "^0.5.1", "js-sha256": "^0.9.0", "js-sha3": "^0.8.0", @@ -2821,19 +2835,25 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==", - "license": "MIT" + "dev": true, + "license": "MIT", + "peer": true }, "node_modules/algosdk/node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "license": "MIT" + "dev": true, + "license": "MIT", + "peer": true }, "node_modules/algosdk/node_modules/js-sha512": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==", - "license": "MIT" + "dev": true, + "license": "MIT", + "peer": true }, "node_modules/ansi-escapes": { "version": "7.0.0", @@ -2898,14 +2918,14 @@ "license": "MIT" }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -2922,20 +2942,19 @@ "license": "MIT" }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -3000,6 +3019,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, "funding": [ { "type": "github", @@ -3057,15 +3077,17 @@ "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "dev": true, "license": "MIT", + "peer": true, "engines": { "node": "*" } }, "node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", + "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==", "license": "MIT" }, "node_modules/bottleneck": { @@ -3109,6 +3131,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, "funding": [ { "type": "github", @@ -3140,17 +3163,47 @@ } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -3187,9 +3240,9 @@ } }, "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.0.tgz", + "integrity": "sha512-ZkD35Mx92acjB2yNJgziGqT9oKHEOxjTBTDRpOsRWtdecL/0jM3z5kM/CTzHWvHIen1GvkM85p6TuFfDGfc8/Q==", "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -4017,21 +4070,21 @@ } }, "node_modules/cosmiconfig-typescript-loader": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.1.0.tgz", - "integrity": "sha512-7PtBB+6FdsOvZyJtlF3hEPpACq7RQX6BVGsgC7/lfVXnKMvNCu/XY3ykreqG5w/rBNdu2z8LCIKoF3kpHHdHlA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.1.0.tgz", + "integrity": "sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==", "dev": true, "license": "MIT", "dependencies": { - "jiti": "^1.21.6" + "jiti": "^2.4.1" }, "engines": { - "node": ">=v16" + "node": ">=v18" }, "peerDependencies": { "@types/node": "*", - "cosmiconfig": ">=8.2", - "typescript": ">=4" + "cosmiconfig": ">=9", + "typescript": ">=5" } }, "node_modules/cross-spawn": { @@ -4091,15 +4144,15 @@ } }, "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4109,31 +4162,31 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -4152,9 +4205,9 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "license": "MIT", "dependencies": { @@ -4278,6 +4331,21 @@ "node": ">=8" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -4328,9 +4396,9 @@ "license": "MIT" }, "node_modules/elliptic": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.0.tgz", - "integrity": "sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "license": "MIT", "dependencies": { "bn.js": "^4.11.9", @@ -4505,58 +4573,60 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.23.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.6.tgz", + "integrity": "sha512-Ifco6n3yj2tMZDWNLyloZrytt9lqqlwvS83P3HtaETR0NUOYnIULGGHpktqYGObGy+8wc1okO25p8TjemhImvA==", "dev": true, "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "data-view-buffer": "^1.0.1", "data-view-byte-length": "^1.0.1", "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.7", + "get-intrinsic": "^1.2.6", "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", + "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", + "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", + "is-regex": "^1.2.1", "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", + "is-string": "^1.1.1", "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.0.0", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-regex-test": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.2", "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", + "typed-array-byte-offset": "^1.0.3", + "typed-array-length": "^1.0.7", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -4566,14 +4636,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -4617,15 +4684,15 @@ } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -5095,9 +5162,9 @@ } }, "node_modules/execa": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.1.tgz", - "integrity": "sha512-QY5PPtSonnGwhhHDNI7+3RvY285c7iuJFFB+lU+oEzMY/gEGJ808owqJsrr8Otd1E/x07po1LkUBmdAc5duPAg==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.2.tgz", + "integrity": "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==", "dev": true, "license": "MIT", "dependencies": { @@ -5343,9 +5410,9 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "dev": true, "license": "ISC" }, @@ -5481,16 +5548,18 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -5520,17 +5589,22 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "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==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -5553,15 +5627,15 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -5793,13 +5867,13 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5842,11 +5916,14 @@ } }, "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5875,11 +5952,14 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -5888,9 +5968,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { @@ -5943,7 +6023,9 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==", - "license": "MIT" + "dev": true, + "license": "MIT", + "peer": true }, "node_modules/highlight.js": { "version": "10.7.3", @@ -6008,13 +6090,13 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -6035,6 +6117,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, "funding": [ { "type": "github", @@ -6178,15 +6261,15 @@ } }, "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -6210,14 +6293,15 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -6233,28 +6317,47 @@ "dev": true, "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "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==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -6277,9 +6380,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz", + "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==", "dev": true, "license": "MIT", "dependencies": { @@ -6293,12 +6396,14 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -6309,13 +6414,14 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -6350,6 +6456,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -6359,6 +6481,22 @@ "node": ">=8" } }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -6372,6 +6510,19 @@ "node": ">=0.10.0" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", @@ -6403,13 +6554,14 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -6452,14 +6604,16 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -6468,14 +6622,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -6498,13 +6665,14 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -6514,13 +6682,15 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -6543,13 +6713,13 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -6571,14 +6741,47 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", + "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6707,13 +6910,13 @@ } }, "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", "dev": true, "license": "MIT", "bin": { - "jiti": "bin/jiti.js" + "jiti": "lib/jiti-cli.mjs" } }, "node_modules/js-sha256": { @@ -6758,7 +6961,9 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { "bignumber.js": "^9.0.0" } @@ -6792,13 +6997,14 @@ "license": "MIT" }, "node_modules/json-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", - "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.2.0.tgz", + "integrity": "sha512-ex8jk9BZHBolvbd5cRnAgwyaYcYB0qZldy1e+LCOdcF6+AUmVZ6LcGUMzsRTW83QMeu+GxZGrcLqxqrgfXGvIw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "isarray": "^2.0.5", "jsonify": "^0.0.1", "object-keys": "^1.1.1" @@ -7083,9 +7289,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.12", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", - "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, "license": "MIT", "dependencies": { @@ -7155,6 +7361,16 @@ "marked": ">=1 <15" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -7222,9 +7438,9 @@ } }, "node_modules/mime": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.4.tgz", - "integrity": "sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.6.tgz", + "integrity": "sha512-4rGt7rvQHBbaSOF9POGkk1ocRP16Md1x36Xma8sz8h8/vfCUI2OtEIeCqe4Ofes853x4xDoPiFLIT47J5fI/7A==", "dev": true, "funding": [ "https://github.com/sponsors/broofa" @@ -7367,9 +7583,9 @@ "license": "MIT" }, "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", "dev": true, "license": "MIT", "dependencies": { @@ -10454,9 +10670,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, "license": "MIT", "engines": { @@ -10477,15 +10693,17 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -10638,9 +10856,9 @@ } }, "node_modules/p-map": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.2.tgz", - "integrity": "sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", "dev": true, "license": "MIT", "engines": { @@ -11090,9 +11308,9 @@ } }, "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -11111,7 +11329,7 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { @@ -11158,9 +11376,9 @@ } }, "node_modules/pretty-ms": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz", - "integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", "dev": true, "license": "MIT", "dependencies": { @@ -11377,6 +11595,29 @@ "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==", + "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-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", @@ -11397,9 +11638,9 @@ } }, "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "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==", "dev": true, "license": "MIT", "dependencies": { @@ -11430,19 +11671,22 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11499,9 +11743,9 @@ } }, "node_modules/rollup": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", - "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz", + "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==", "dev": true, "license": "MIT", "dependencies": { @@ -11515,24 +11759,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.3", - "@rollup/rollup-android-arm64": "4.24.3", - "@rollup/rollup-darwin-arm64": "4.24.3", - "@rollup/rollup-darwin-x64": "4.24.3", - "@rollup/rollup-freebsd-arm64": "4.24.3", - "@rollup/rollup-freebsd-x64": "4.24.3", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", - "@rollup/rollup-linux-arm-musleabihf": "4.24.3", - "@rollup/rollup-linux-arm64-gnu": "4.24.3", - "@rollup/rollup-linux-arm64-musl": "4.24.3", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", - "@rollup/rollup-linux-riscv64-gnu": "4.24.3", - "@rollup/rollup-linux-s390x-gnu": "4.24.3", - "@rollup/rollup-linux-x64-gnu": "4.24.3", - "@rollup/rollup-linux-x64-musl": "4.24.3", - "@rollup/rollup-win32-arm64-msvc": "4.24.3", - "@rollup/rollup-win32-ia32-msvc": "4.24.3", - "@rollup/rollup-win32-x64-msvc": "4.24.3", + "@rollup/rollup-android-arm-eabi": "4.28.1", + "@rollup/rollup-android-arm64": "4.28.1", + "@rollup/rollup-darwin-arm64": "4.28.1", + "@rollup/rollup-darwin-x64": "4.28.1", + "@rollup/rollup-freebsd-arm64": "4.28.1", + "@rollup/rollup-freebsd-x64": "4.28.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.28.1", + "@rollup/rollup-linux-arm-musleabihf": "4.28.1", + "@rollup/rollup-linux-arm64-gnu": "4.28.1", + "@rollup/rollup-linux-arm64-musl": "4.28.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.28.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1", + "@rollup/rollup-linux-riscv64-gnu": "4.28.1", + "@rollup/rollup-linux-s390x-gnu": "4.28.1", + "@rollup/rollup-linux-x64-gnu": "4.28.1", + "@rollup/rollup-linux-x64-musl": "4.28.1", + "@rollup/rollup-win32-arm64-msvc": "4.28.1", + "@rollup/rollup-win32-ia32-msvc": "4.28.1", + "@rollup/rollup-win32-x64-msvc": "4.28.1", "fsevents": "~2.3.2" } }, @@ -11561,15 +11806,16 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -11587,15 +11833,15 @@ "license": "MIT" }, "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -11649,9 +11895,9 @@ } }, "node_modules/semantic-release/node_modules/hosted-git-info": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.0.tgz", - "integrity": "sha512-4nw3vOVR+vHUOT8+U4giwe2tcGv+R3pwwRidUe67DoMBTjhrfr6rZYJVVwdkBE+Um050SG+X9tf0Jo4fOpn01w==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.2.tgz", + "integrity": "sha512-sYKnA7eGln5ov8T8gnYlkSOxFJvywzEx9BueN6xo/GKO8PGiI6uK6xx+DIGe45T3bdVjLAQDQW1aicT8z8JwQg==", "dev": true, "license": "ISC", "dependencies": { @@ -11766,26 +12012,86 @@ } }, "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -12047,9 +12353,9 @@ "license": "MIT" }, "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", "dev": true, "license": "MIT" }, @@ -12183,16 +12489,19 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -12202,16 +12511,20 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -12385,9 +12698,9 @@ } }, "node_modules/table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -12728,9 +13041,9 @@ "license": "MIT" }, "node_modules/tinypool": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", - "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", "dev": true, "license": "MIT", "engines": { @@ -12797,9 +13110,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", - "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "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==", "dev": true, "license": "MIT", "engines": { @@ -12855,9 +13168,9 @@ } }, "node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "version": "4.30.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.30.2.tgz", + "integrity": "sha512-UJShLPYi1aWqCdq9HycOL/gwsuqda1OISdBO3t8RlXQC4QvtuIz4b5FCfe2dQIWEpmlRExKmcTBfP1r9bhY7ig==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -12868,32 +13181,32 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -12903,18 +13216,19 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -12924,18 +13238,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -12972,16 +13286,19 @@ } }, "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -13109,9 +13426,9 @@ } }, "node_modules/vite": { - "version": "5.4.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", - "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -13689,7 +14006,9 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==", - "license": "MIT" + "dev": true, + "license": "MIT", + "peer": true }, "node_modules/which": { "version": "2.0.2", @@ -13707,33 +14026,84 @@ } }, "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "for-each": "^0.3.3", - "gopd": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -13926,9 +14296,9 @@ } }, "node_modules/yaml": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", - "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", "dev": true, "license": "ISC", "bin": { diff --git a/package.json b/package.json index b2d7492..513f04a 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "build-examples": "rollup --config examples/rollup.config.ts --configPlugin typescript" }, "devDependencies": { + "@algorandfoundation/algokit-utils": "^8.0.3", "@commitlint/cli": "^19.5.0", "@commitlint/config-conventional": "^19.5.0", "@eslint/eslintrc": "3.1.0", @@ -62,10 +63,8 @@ "tslib": "^2.6.2" }, "dependencies": { - "@algorandfoundation/algokit-utils": "^6.2.1", "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.22", "@algorandfoundation/puya-ts": "^1.0.0-alpha.34", - "algosdk": "^2.9.0", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", diff --git a/src/abi-metadata.ts b/src/abi-metadata.ts index 57723a6..9e97a2e 100644 --- a/src/abi-metadata.ts +++ b/src/abi-metadata.ts @@ -1,6 +1,6 @@ import { BaseContract, Contract } from '@algorandfoundation/algorand-typescript' import { AbiMethodConfig, BareMethodConfig, CreateOptions, OnCompleteActionStr } from '@algorandfoundation/algorand-typescript/arc4' -import { ABIMethod } from 'algosdk' +import { sha512_256 as js_sha512_256 } from 'js-sha512' import { TypeInfo } from './encoders' import { getArc4TypeName as getArc4TypeNameForARC4Encoded } from './impl/encoded-types' import { DeliberateAny } from './typescript-helpers' @@ -73,12 +73,16 @@ 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) - const method = new ABIMethod({ name: metadata.methodName, args: argTypes.map((t) => ({ type: t })), returns: { type: returnType } }) - metadata.methodSignature = method.getSignature() + metadata.methodSignature = `${metadata.methodName}(${argTypes.join(',')})${returnType}` } return metadata.methodSignature } +export const getArc4Selector = (metadata: AbiMetadata): Uint8Array => { + const hash = js_sha512_256.array(getArc4Signature(metadata)) + return new Uint8Array(hash.slice(0, 4)) +} + const getArc4TypeName = (t: TypeInfo): string => { const map: Record string)> = { void: 'void', diff --git a/src/constants.ts b/src/constants.ts index 2536444..2637b14 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -43,3 +43,22 @@ export const ABI_RETURN_VALUE_LOG_PREFIX = Bytes.fromHex('151F7C75') export const UINT64_OVERFLOW_UNDERFLOW_MESSAGE = 'Uint64 overflow or underflow' export const BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE = 'BigUint overflow or underflow' + +export const APP_ID_PREFIX = 'appID' +export const HASH_BYTES_LENGTH = 32 +export const ALGORAND_ADDRESS_BYTE_LENGTH = 36 +export const ALGORAND_CHECKSUM_BYTE_LENGTH = 4 +export const ALGORAND_ADDRESS_LENGTH = 58 + +export const PROGRAM_TAG = 'Program' + +export const TRANSACTION_GROUP_MAX_SIZE = 16 + +export enum OnApplicationComplete { + NoOpOC = 0, + OptInOC = 1, + CloseOutOC = 2, + ClearStateOC = 3, + UpdateApplicationOC = 4, + DeleteApplicationOC = 5, +} diff --git a/src/impl/application.ts b/src/impl/application.ts index 013b3b3..9ae03cd 100644 --- a/src/impl/application.ts +++ b/src/impl/application.ts @@ -1,10 +1,9 @@ -import { Account, Application, Bytes, bytes, LocalState, uint64 } from '@algorandfoundation/algorand-typescript' -import algosdk from 'algosdk' +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 { asBigInt, asUint64 } from '../util' +import { asUint64, getApplicationAddress } from '../util' import { Uint64BackedCls } from './base' import { GlobalStateCls } from './state' @@ -76,7 +75,6 @@ export class ApplicationCls extends Uint64BackedCls implements Application { return this.data.application.creator } get address(): Account { - const addr = algosdk.getApplicationAddress(asBigInt(this.id)) - return Account(Bytes.fromBase32(addr)) + return getApplicationAddress(this.id) } } diff --git a/src/impl/crypto.ts b/src/impl/crypto.ts index 7cdbd46..6089807 100644 --- a/src/impl/crypto.ts +++ b/src/impl/crypto.ts @@ -1,14 +1,13 @@ import { arc4, bytes, Bytes, Ecdsa, gtxn, internal, VrfVerify } from '@algorandfoundation/algorand-typescript' -import algosdk from 'algosdk' 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 nacl from 'tweetnacl' -import { LOGIC_DATA_PREFIX } from '../constants' +import { LOGIC_DATA_PREFIX, PROGRAM_TAG } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { notImplementedError } from '../errors' -import { asBytes, asBytesCls } from '../util' +import { asBytes, asBytesCls, asUint8Array, conactUint8Arrays } from '../util' export const sha256 = (a: internal.primitives.StubBytesCompat): bytes => { const bytesA = internal.primitives.BytesCls.fromCompat(a) @@ -59,10 +58,10 @@ export const ed25519verify = ( txn.onCompletion == arc4.OnCompleteAction[arc4.OnCompleteAction.ClearState] ? txn.clearStateProgram : txn.approvalProgram, ) - const logicSig = new algosdk.LogicSig(programBytes.asUint8Array()) - const decodedAddress = algosdk.decodeAddress(logicSig.address()) + const logicSig = conactUint8Arrays(asUint8Array(PROGRAM_TAG), programBytes.asUint8Array()) + const logicSigAddress = js_sha512_256.array(logicSig) - const addressBytes = Bytes(decodedAddress.publicKey) + const addressBytes = Bytes(logicSigAddress) const data = LOGIC_DATA_PREFIX.concat(addressBytes).concat(asBytes(a)) return ed25519verifyBare(data, b, c) } diff --git a/src/impl/encoded-types.ts b/src/impl/encoded-types.ts index 178a991..a9a7d26 100644 --- a/src/impl/encoded-types.ts +++ b/src/impl/encoded-types.ts @@ -16,9 +16,14 @@ import { UintN, } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' -import { decodeAddress } from 'algosdk' import assert from 'assert' -import { ABI_RETURN_VALUE_LOG_PREFIX, BITS_IN_BYTE, UINT64_SIZE } from '../constants' +import { + ABI_RETURN_VALUE_LOG_PREFIX, + ALGORAND_ADDRESS_BYTE_LENGTH, + ALGORAND_CHECKSUM_BYTE_LENGTH, + BITS_IN_BYTE, + UINT64_SIZE, +} from '../constants' import { fromBytes, TypeInfo } from '../encoders' import { DeliberateAny } from '../typescript-helpers' import { asBigUint, asBigUintCls, asBytesCls, asUint64, asUint8Array, conactUint8Arrays, uint8ArrayToNumber } from '../util' @@ -429,7 +434,7 @@ export class AddressImpl extends Address { if (value === undefined) { uint8ArrayValue = new Uint8Array(32) } else if (typeof value === 'string') { - uint8ArrayValue = decodeAddress(value).publicKey + 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 { diff --git a/src/impl/global.ts b/src/impl/global.ts index 06921dc..5418937 100644 --- a/src/impl/global.ts +++ b/src/impl/global.ts @@ -1,5 +1,4 @@ import { Account, Application, Bytes, bytes, internal, op, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' -import algosdk from 'algosdk' import { DEFAULT_ACCOUNT_MIN_BALANCE, DEFAULT_ASSET_CREATE_MIN_BALANCE, @@ -10,7 +9,7 @@ import { ZERO_ADDRESS, } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { asBigInt, getObjectReference } from '../util' +import { getApplicationAddress, getObjectReference } from '../util' export class GlobalData { minTxnFee: uint64 @@ -128,8 +127,7 @@ export const Global: internal.opTypes.GlobalType = { * Address that the current application controls. Application mode only. */ get currentApplicationAddress(): Account { - const appAddress = algosdk.getApplicationAddress(asBigInt(this.currentApplicationId.id)) - return Account(Bytes.fromBase32(appAddress)) + return this.currentApplicationId.address }, /** @@ -163,8 +161,7 @@ export const Global: internal.opTypes.GlobalType = { * The application address of the application that called this application. ZeroAddress if this application is at the top-level. Application mode only. */ get callerApplicationAddress(): Account { - const appAddress = algosdk.getApplicationAddress(asBigInt(this.callerApplicationId)) - return Account(Bytes.fromBase32(appAddress)) + return getApplicationAddress(this.callerApplicationId) }, /** diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 26b7d62..7f60248 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -10,11 +10,10 @@ import { internal, LocalState, } from '@algorandfoundation/algorand-typescript' -import { ABIMethod } from 'algosdk' import { AbiMetadata, copyAbiMetadatas, - getArc4Signature, + getArc4Selector, getContractAbiMetadata, getContractMethodAbiMetadata, isContractProxy, @@ -144,7 +143,7 @@ export class ContractContext { ...args: TParams ): Transaction[] { const app = lazyContext.ledger.getApplicationForContract(contract) - const methodSelector = abiMetadata ? ABIMethod.fromSignature(getArc4Signature(abiMetadata)).getSelector() : new Uint8Array() + const methodSelector = abiMetadata ? getArc4Selector(abiMetadata) : new Uint8Array() const { transactions, ...appCallArgs } = extractArraysFromArgs(app, methodSelector, args) const appTxn = lazyContext.any.txn.applicationCall({ appId: app, diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index dacd212..04e1863 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -1,6 +1,6 @@ import { bytes, Contract, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' -import algosdk from 'algosdk' import { AbiMetadata, getContractMethodAbiMetadata } from '../abi-metadata' +import { TRANSACTION_GROUP_MAX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' import { DecodedLogs, decodeLogs, LogDecoding } from '../decode-logs' import { testInvariant } from '../errors' @@ -180,10 +180,8 @@ export class TransactionGroup { constructor(transactions: Transaction[], activeTransactionIndex?: number) { this.latestTimestamp = Date.now() - if (transactions.length > algosdk.AtomicTransactionComposer.MAX_GROUP_SIZE) { - internal.errors.internalError( - `Transaction group can have at most ${algosdk.AtomicTransactionComposer.MAX_GROUP_SIZE} transactions, as per AVM limits.`, - ) + 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.`) } transactions.forEach((txn, index) => Object.assign(txn, { groupIndex: asUint64(index) })) this.activeTransactionIndex = activeTransactionIndex === undefined ? transactions.length - 1 : activeTransactionIndex @@ -245,8 +243,8 @@ export class TransactionGroup { if (!this.constructingItxnGroup.length) { internal.errors.internalError('itxn submit without itxn begin') } - if (this.constructingItxnGroup.length > algosdk.AtomicTransactionComposer.MAX_GROUP_SIZE) { - internal.errors.internalError('Cannot submit more than 16 inner transactions at once') + if (this.constructingItxnGroup.length > TRANSACTION_GROUP_MAX_SIZE) { + internal.errors.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) })) diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index 250e3ab..f86e183 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -1,5 +1,4 @@ -import { Account, Application, Asset, Bytes, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' -import algosdk from 'algosdk' +import { Account, Application, Asset, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { captureMethodConfig } from './abi-metadata' import { DecodedLogs, LogDecoding } from './decode-logs' import * as ops from './impl' @@ -19,6 +18,7 @@ import { Box, BoxMap, BoxRef, GlobalState, LocalState } from './impl/state' import { ContractContext } from './subcontexts/contract-context' import { LedgerContext } from './subcontexts/ledger-context' import { TransactionContext } from './subcontexts/transaction-context' +import { getRandomBytes } from './util' import { ValueGenerator } from './value-generators' export class TestExecutionContext implements internal.ExecutionContext { @@ -34,7 +34,7 @@ export class TestExecutionContext implements internal.ExecutionContext { this.#ledgerContext = new LedgerContext() this.#txnContext = new TransactionContext() this.#valueGenerator = new ValueGenerator() - this.#defaultSender = Account(defaultSenderAddress ?? Bytes.fromBase32(algosdk.generateAccount().addr)) + this.#defaultSender = Account(defaultSenderAddress ?? getRandomBytes(32).asAlgoTs()) } account(address?: bytes): Account { diff --git a/src/util.ts b/src/util.ts index 31d3211..ff0ec08 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,7 +1,20 @@ -import { Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' +import { Account, Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' +import { encodingUtil } from '@algorandfoundation/puya-ts' import { randomBytes } from 'crypto' -import { BITS_IN_BYTE, MAX_BYTES_SIZE, MAX_UINT512, MAX_UINT8, UINT512_SIZE } from './constants' +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 { BytesBackedCls, Uint64BackedCls } from './impl/base' import { DeliberateAny } from './typescript-helpers' @@ -192,3 +205,25 @@ export const conactUint8Arrays = (...values: Uint8Array[]): Uint8Array => { 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) +} + +export const decodePublicKey = (address: string): Uint8Array => { + const decoded = encodingUtil.base32ToUint8Array(address) + return decoded.slice(0, ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH) +} diff --git a/src/value-generators/avm.ts b/src/value-generators/avm.ts index b328f01..a79ec08 100644 --- a/src/value-generators/avm.ts +++ b/src/value-generators/avm.ts @@ -1,12 +1,11 @@ import { Account, Application, Asset, bytes, Bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' -import algosdk from 'algosdk' import { randomBytes } from 'crypto' import { MAX_BYTES_SIZE, MAX_UINT64, ZERO_ADDRESS } 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 } from '../util' +import { asBigInt, asUint64Cls, getRandomBigInt, getRandomBytes } from '../util' type AccountContextData = Partial & { address?: Account @@ -37,7 +36,7 @@ export class AvmValueGenerator { } account(input?: AccountContextData): Account { - const account = input?.address ?? Account(Bytes.fromBase32(algosdk.generateAccount().addr)) + const account = input?.address ?? Account(getRandomBytes(32).asAlgoTs()) if (input?.address && lazyContext.ledger.accountDataMap.has(account)) { internal.errors.internalError( diff --git a/tests/arc4/address.spec.ts b/tests/arc4/address.spec.ts index 905504b..6b388f8 100644 --- a/tests/arc4/address.spec.ts +++ b/tests/arc4/address.spec.ts @@ -1,12 +1,13 @@ +import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' import { Account, Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { Address, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' -import { ABIType, encodeAddress } from 'algosdk' import { afterEach, describe, expect, test } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX } from '../../src/constants' +import { encodeAddress } from '../../src/util' import { asUint8Array } from '../util' -const abiAddressType = ABIType.from('address') +const abiTypeString = 'address' const testData = [ Bytes.fromHex('00'.repeat(32)), Bytes.fromHex('01'.repeat(32)), @@ -21,19 +22,19 @@ describe('arc4.Address', async () => { }) test.each(testData)('create address from bytes', async (value) => { - const sdkResult = abiAddressType.encode(asUint8Array(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) => { const stringValue = encodeAddress(asUint8Array(value)) - const sdkResult = abiAddressType.encode(stringValue) + const sdkResult = getABIEncodedValue(stringValue, abiTypeString, {}) const result = new Address(stringValue) expect(result.bytes).toEqual(sdkResult) }) test.each(testData)('create address from Account', async (value) => { const accountValue = Account(value) - const sdkResult = abiAddressType.encode(asUint8Array(accountValue.bytes)) + const sdkResult = getABIEncodedValue(asUint8Array(accountValue.bytes), abiTypeString, {}) const result = new Address(accountValue) expect(result.bytes).toEqual(sdkResult) }) @@ -69,13 +70,13 @@ describe('arc4.Address', async () => { }) test.each(testData)('fromBytes method', async (value) => { - const sdkResult = abiAddressType.encode(asUint8Array(value)) + const sdkResult = getABIEncodedValue(asUint8Array(value), abiTypeString, {}) const result = interpretAsArc4
(value) expect(result.bytes).toEqual(sdkResult) }) test.each(testData)('fromLog method', async (value) => { - const sdkResult = abiAddressType.encode(asUint8Array(value)) + const sdkResult = getABIEncodedValue(asUint8Array(value), abiTypeString, {}) const paddedValue = Bytes([...asUint8Array(ABI_RETURN_VALUE_LOG_PREFIX), ...asUint8Array(value)]) const result = interpretAsArc4
(paddedValue, 'log') expect(result.bytes).toEqual(sdkResult) diff --git a/tests/arc4/dynamic-array.spec.ts b/tests/arc4/dynamic-array.spec.ts index 836a83e..ee70df1 100644 --- a/tests/arc4/dynamic-array.spec.ts +++ b/tests/arc4/dynamic-array.spec.ts @@ -1,3 +1,4 @@ +import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' import { Bytes, internal } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { @@ -13,14 +14,13 @@ import { UintN, } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' -import { ABIType } from 'algosdk' import { afterEach, describe, expect, it, test } from 'vitest' import { AccountCls } from '../../src/impl/account' import { DeliberateAny } from '../../src/typescript-helpers' import { asBytes, asUint8Array } from '../../src/util' const addressDynamicArray = { - abiType: ABIType.from('address[]'), + abiTypeString: 'address[]', nativeValues() { return [ asUint8Array(Bytes.fromHex('00'.repeat(32))), @@ -46,7 +46,7 @@ const addressDynamicArray = { }, } const boolDynamicArray = { - abiType: ABIType.from('bool[]'), + abiTypeString: 'bool[]', nativeValues() { return [true, true, false, true, false, true, true, false, true, false] }, @@ -61,7 +61,7 @@ const boolDynamicArray = { }, } const uint256DynamicArray = { - abiType: ABIType.from('uint256[]'), + abiTypeString: 'uint256[]', nativeValues() { return [0n, 1n, 2n, 3n, 2n ** 8n, 2n ** 16n, 2n ** 32n, 2n ** 64n, 2n ** 128n, 2n ** 256n - 1n] }, @@ -76,7 +76,7 @@ const uint256DynamicArray = { }, } const ufixednxmDynamicArray = { - abiType: ABIType.from('ufixed256x16[]'), + abiTypeString: 'ufixed256x16[]', nativeValues() { return this.abiValues().map((v) => v.native.valueOf()) }, @@ -102,7 +102,7 @@ const ufixednxmDynamicArray = { }, } const stringDynamicArray = { - abiType: ABIType.from('string[]'), + abiTypeString: 'string[]', nativeValues() { return [ '', @@ -128,7 +128,7 @@ const stringDynamicArray = { }, } const boolDynamicArrayOfArray = { - abiType: ABIType.from('bool[][]'), + abiTypeString: 'bool[][]', nativeValues() { return [boolDynamicArray.nativeValues(), boolDynamicArray.nativeValues().reverse()] }, @@ -145,7 +145,7 @@ const boolDynamicArrayOfArray = { }, } const addressDynamicArrayOfArray = { - abiType: ABIType.from('address[][]'), + abiTypeString: 'address[][]', nativeValues() { return [addressDynamicArray.nativeValues(), addressDynamicArray.nativeValues().reverse()] }, @@ -162,7 +162,7 @@ const addressDynamicArrayOfArray = { }, } const uint256DynamicArrayOfArray = { - abiType: ABIType.from('uint256[][]'), + abiTypeString: 'uint256[][]', nativeValues() { return [uint256DynamicArray.nativeValues(), uint256DynamicArray.nativeValues().reverse()] }, @@ -179,7 +179,7 @@ const uint256DynamicArrayOfArray = { }, } const uint256DynamicArrayOfStaticArray = { - abiType: ABIType.from('uint256[10][]'), + abiTypeString: 'uint256[10][]', nativeValues() { return [uint256DynamicArray.nativeValues(), uint256DynamicArray.nativeValues().reverse()] }, @@ -196,7 +196,7 @@ const uint256DynamicArrayOfStaticArray = { }, } const stringDynamicArrayOfArray = { - abiType: ABIType.from('string[][]'), + abiTypeString: 'string[][]', nativeValues() { return [stringDynamicArray.nativeValues(), stringDynamicArray.nativeValues().reverse()] }, @@ -213,7 +213,7 @@ const stringDynamicArrayOfArray = { }, } const stringDynamicArrayOfArrayOfArray = { - abiType: ABIType.from('string[][][]'), + abiTypeString: 'string[][][]', nativeValues() { return [ [stringDynamicArray.nativeValues(), stringDynamicArray.nativeValues().reverse(), stringDynamicArray.nativeValues()], @@ -235,7 +235,7 @@ const stringDynamicArrayOfArrayOfArray = { }, } const tupleDynamicArray = { - abiType: ABIType.from('(string[],(string[],string,uint256,address),bool,uint256[3])[]'), + abiTypeString: '(string[],(string[],string,uint256,address),bool,uint256[3])[]', nativeValues() { return Array(2).fill([ stringDynamicArray.nativeValues().slice(0, 2), @@ -288,7 +288,7 @@ class Swapped extends Struct<{ a: Tuple<[DynamicArray, DynamicArray, Str, UintN<256>, Bool, StaticArray, 3>]> }> {} const structDynamicArray = { - abiType: ABIType.from('(uint256,bool,string,(string[],string[],string,uint256,bool,uint256[3]))[]'), + abiTypeString: '(uint256,bool,string,(string[],string[],string,uint256,bool,uint256[3]))[]', nativeValues() { return Array(2).fill([ uint256DynamicArray.nativeValues()[0], @@ -354,7 +354,7 @@ describe('arc4.DynamicArray', async () => { tupleDynamicArray, structDynamicArray, ])('should be able to get bytes representation', async (data) => { - const sdkResult = data.abiType.encode(data.nativeValues()) + const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.array().bytes expect(result).toEqual(sdkResult) }) @@ -374,7 +374,7 @@ describe('arc4.DynamicArray', async () => { tupleDynamicArray, structDynamicArray, ])('copy dynamic array', async (data) => { - const sdkResult = data.abiType.encode(data.nativeValues()) + const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const original = data.array() const copy = original.copy() const result = copy.bytes @@ -432,7 +432,7 @@ describe('arc4.DynamicArray', async () => { dynamicArrayCopy[dynamicArrayCopy.length - 1] = dynamicArrayCopy[0] dynamicArrayCopy[0] = arrayTemp - const sdkResult = data.abiType.encode(nativeValuesCopy) + const sdkResult = getABIEncodedValue(nativeValuesCopy, data.abiTypeString, {}) const result = dynamicArrayCopy.bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -452,7 +452,7 @@ describe('arc4.DynamicArray', async () => { tupleDynamicArray, structDynamicArray, ])('create dynamic array from bytes', async (data) => { - const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const sdkEncodedBytes = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.create(Bytes(sdkEncodedBytes)) const nativeValues = data.nativeValues() for (let i = 0; i < result.length; i++) { @@ -484,7 +484,7 @@ describe('arc4.DynamicArray', async () => { const dynamicArrayCopy = dynamicArray.copy() dynamicArrayCopy.push(dynamicArray.at(-1) as never, dynamicArray[0] as never) - const sdkResult = data.abiType.encode(nativeValuesCopy) + const sdkResult = getABIEncodedValue(nativeValuesCopy, data.abiTypeString, {}) const result = dynamicArrayCopy.bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -505,7 +505,7 @@ describe('arc4.DynamicArray', async () => { structDynamicArray, ])('push item to empty dynamic array', async (data) => { const nativeValues = data.nativeValues() - const sdkResult = data.abiType.encode(nativeValues) + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) const emptyArray = data.array(true) data.abiValues().forEach((v) => emptyArray.push(v as never)) @@ -529,9 +529,9 @@ describe('arc4.DynamicArray', async () => { structDynamicArray, ])('push item to empty dynamic array created from bytes', async (data) => { const nativeValues = data.nativeValues() - const sdkResult = data.abiType.encode(nativeValues) + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) - const emptyArray = data.create(Bytes(data.abiType.encode([]))) + const emptyArray = data.create(Bytes(getABIEncodedValue([], data.abiTypeString, {}))) data.abiValues().forEach((v) => emptyArray.push(v as never)) expect(emptyArray.length).toEqual(nativeValues.length) expect(emptyArray.bytes).toEqual(sdkResult) @@ -565,7 +565,7 @@ describe('arc4.DynamicArray', async () => { compareARC4AndABIValue(value1, nativeValue1) compareARC4AndABIValue(value2, nativeValue2) - const sdkResult = data.abiType.encode(nativeValuesCopy) + const sdkResult = getABIEncodedValue(nativeValuesCopy, data.abiTypeString, {}) const result = dynamicArrayCopy.bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -578,7 +578,7 @@ describe('arc4.DynamicArray', async () => { const dynamicArray = data.array() dynamicArray[0][0][0] = new Str('new value') - const sdkResult = data.abiType.encode(nativeValues) + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) const result = dynamicArray.bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -588,11 +588,11 @@ describe('arc4.DynamicArray', async () => { const nativeValues = data.nativeValues() nativeValues[0][0][0] = 'new value' - const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const sdkEncodedBytes = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const dynamicArray = data.create(Bytes(sdkEncodedBytes)) dynamicArray[0][0][0] = new Str('new value') - const sdkResult = data.abiType.encode(nativeValues) + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) const result = dynamicArray.bytes expect(result).toEqual(Bytes(sdkResult)) }) diff --git a/tests/arc4/dynamic-bytes.spec.ts b/tests/arc4/dynamic-bytes.spec.ts index ee1bfc2..4935f31 100644 --- a/tests/arc4/dynamic-bytes.spec.ts +++ b/tests/arc4/dynamic-bytes.spec.ts @@ -1,10 +1,10 @@ +import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' import { Bytes } from '@algorandfoundation/algorand-typescript' import { DynamicBytes, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' -import { ABIType } from 'algosdk' import { describe, expect, test } from 'vitest' -const abiType = ABIType.from('byte[]') +const abiTypeString = 'byte[]' const testData = [ { nativeValue() { @@ -16,7 +16,7 @@ const testData = [ }, { nativeValue() { - return encodingUtil.utf8ToUint8Array('01ff99aa'.repeat(8)) + return [...encodingUtil.utf8ToUint8Array('01ff99aa'.repeat(8))] }, dynamicBytes() { return new DynamicBytes('01ff99aa'.repeat(8)) @@ -26,7 +26,7 @@ const testData = [ describe('arc4.DynamicBytes', async () => { test.each(testData)('should be able to get bytes representation', async (data) => { - const sdkResult = abiType.encode(data.nativeValue()) + const sdkResult = getABIEncodedValue(data.nativeValue(), abiTypeString, {}) const result = data.dynamicBytes().bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -42,7 +42,7 @@ describe('arc4.DynamicBytes', async () => { test.each(testData)('create dynamic bytes from bytes', async (data) => { const nativeValue = data.nativeValue() - const sdkEncodedBytes = abiType.encode(nativeValue) + const sdkEncodedBytes = getABIEncodedValue(nativeValue, abiTypeString, {}) const result = interpretAsArc4(Bytes(sdkEncodedBytes)) for (let i = 0; i < result.length; i++) { expect(result[i].native).toEqual(nativeValue[i]) diff --git a/tests/arc4/static-array.spec.ts b/tests/arc4/static-array.spec.ts index 85a19b4..53e6e4c 100644 --- a/tests/arc4/static-array.spec.ts +++ b/tests/arc4/static-array.spec.ts @@ -1,3 +1,4 @@ +import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' import { Bytes, internal } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { @@ -13,14 +14,13 @@ import { UintN, } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' -import { ABIType } from 'algosdk' import { afterEach, describe, expect, it, test } from 'vitest' import { AccountCls } from '../../src/impl/account' import { DeliberateAny } from '../../src/typescript-helpers' import { asBytes, asUint8Array } from '../../src/util' const addressStaticArray = { - abiType: ABIType.from('address[10]'), + abiTypeString: 'address[10]', nativeValues() { return [ asUint8Array(Bytes.fromHex('00'.repeat(32))), @@ -46,7 +46,7 @@ const addressStaticArray = { }, } const boolStaticArray = { - abiType: ABIType.from('bool[10]'), + abiTypeString: 'bool[10]', nativeValues() { return [true, true, false, true, false, true, true, false, true, false] }, @@ -61,7 +61,7 @@ const boolStaticArray = { }, } const uint256StaticArray = { - abiType: ABIType.from('uint256[10]'), + abiTypeString: 'uint256[10]', nativeValues() { return [0n, 1n, 2n, 3n, 2n ** 8n, 2n ** 16n, 2n ** 32n, 2n ** 64n, 2n ** 128n, 2n ** 256n - 1n] }, @@ -76,7 +76,7 @@ const uint256StaticArray = { }, } const ufixednxmStaticArray = { - abiType: ABIType.from('ufixed256x16[10]'), + abiTypeString: 'ufixed256x16[10]', nativeValues() { return this.abiValues().map((v) => v.native.valueOf()) }, @@ -102,7 +102,7 @@ const ufixednxmStaticArray = { }, } const stringStaticArray = { - abiType: ABIType.from('string[10]'), + abiTypeString: 'string[10]', nativeValues() { return [ '', @@ -128,7 +128,7 @@ const stringStaticArray = { }, } const addressStaticArrayOfArray = { - abiType: ABIType.from('address[10][2]'), + abiTypeString: 'address[10][2]', nativeValues() { return [addressStaticArray.nativeValues(), addressStaticArray.nativeValues().reverse()] }, @@ -143,7 +143,7 @@ const addressStaticArrayOfArray = { }, } const boolStaticArrayOfArray = { - abiType: ABIType.from('bool[10][2]'), + abiTypeString: 'bool[10][2]', nativeValues() { return [boolStaticArray.nativeValues(), boolStaticArray.nativeValues().reverse()] }, @@ -158,7 +158,7 @@ const boolStaticArrayOfArray = { }, } const uint256StaticArrayOfArray = { - abiType: ABIType.from('uint256[10][2]'), + abiTypeString: 'uint256[10][2]', nativeValues() { return [uint256StaticArray.nativeValues(), uint256StaticArray.nativeValues().reverse()] }, @@ -173,7 +173,7 @@ const uint256StaticArrayOfArray = { }, } const uint256StaticArrayOfDynamicArray = { - abiType: ABIType.from('uint256[][2]'), + abiTypeString: 'uint256[][2]', nativeValues() { return [uint256StaticArray.nativeValues(), uint256StaticArray.nativeValues().reverse()] }, @@ -188,7 +188,7 @@ const uint256StaticArrayOfDynamicArray = { }, } const stringStaticArrayOfArray = { - abiType: ABIType.from('string[10][2]'), + abiTypeString: 'string[10][2]', nativeValues() { return [stringStaticArray.nativeValues(), stringStaticArray.nativeValues().reverse()] }, @@ -203,7 +203,7 @@ const stringStaticArrayOfArray = { }, } const stringStaticArrayOfArrayOfArray = { - abiType: ABIType.from('string[10][3][2]'), + abiTypeString: 'string[10][3][2]', nativeValues() { return [ [stringStaticArray.nativeValues(), stringStaticArray.nativeValues().reverse(), stringStaticArray.nativeValues()], @@ -225,7 +225,7 @@ const stringStaticArrayOfArrayOfArray = { }, } const tupleStaticArray = { - abiType: ABIType.from('(string[],(string[],string,uint256,address),bool,uint256[3])[2]'), + abiTypeString: '(string[],(string[],string,uint256,address),bool,uint256[3])[2]', nativeValues() { return Array(2).fill([ stringStaticArray.nativeValues().slice(0, 2), @@ -275,7 +275,7 @@ class Swapped extends Struct<{ a: Tuple<[DynamicArray, DynamicArray, Str, UintN<256>, Bool, StaticArray, 3>]> }> {} const structStaticArray = { - abiType: ABIType.from('(uint256,bool,string,(string[],string[],string,uint256,bool,uint256[3]))[2]'), + abiTypeString: '(uint256,bool,string,(string[],string[],string,uint256,bool,uint256[3]))[2]', nativeValues() { return Array(2).fill([ uint256StaticArray.nativeValues()[0], @@ -341,7 +341,7 @@ describe('arc4.StaticArray', async () => { tupleStaticArray, structStaticArray, ])('should be able to get bytes representation', async (data) => { - const sdkResult = data.abiType.encode(data.nativeValues()) + const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.array().bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -361,7 +361,7 @@ describe('arc4.StaticArray', async () => { tupleStaticArray, structStaticArray, ])('copy static array', async (data) => { - const sdkResult = data.abiType.encode(data.nativeValues()) + const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const original = data.array() const copy = original.copy() const result = copy.bytes @@ -419,7 +419,7 @@ describe('arc4.StaticArray', async () => { staticArrayCopy[staticArrayCopy.length - 1] = staticArrayCopy[0] staticArrayCopy[0] = arrayTemp - const sdkResult = data.abiType.encode(nativeValuesCopy) + const sdkResult = getABIEncodedValue(nativeValuesCopy, data.abiTypeString, {}) const result = staticArrayCopy.bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -439,7 +439,7 @@ describe('arc4.StaticArray', async () => { tupleStaticArray, structStaticArray, ])('create static array from bytes', async (data) => { - const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const sdkEncodedBytes = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.create(Bytes(sdkEncodedBytes)) const nativeValues = data.nativeValues() for (let i = 0; i < result.length; i++) { @@ -463,7 +463,7 @@ describe('arc4.StaticArray', async () => { structStaticArray, ])('get item from static array created from bytes', async (data) => { const nativeValues = data.nativeValues() - const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const sdkEncodedBytes = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const staticArray = data.create(Bytes(sdkEncodedBytes)) for (let i = 0; i < staticArray.length; i++) { compareARC4AndABIValue(staticArray[i], nativeValues[i]) @@ -492,14 +492,14 @@ describe('arc4.StaticArray', async () => { nativeValuesCopy[nativeValuesCopy.length - 1] = nativeValuesCopy[0] nativeValuesCopy[0] = nativeTemp - const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const sdkEncodedBytes = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const staticArray = data.create(Bytes(sdkEncodedBytes)) const staticArrayCopy = staticArray.copy() const arrayTemp = staticArrayCopy.at(-1) staticArrayCopy[staticArrayCopy.length - 1] = staticArrayCopy[0] staticArrayCopy[0] = arrayTemp - const sdkResult = data.abiType.encode(nativeValuesCopy) + const sdkResult = getABIEncodedValue(nativeValuesCopy, data.abiTypeString, {}) const result = staticArrayCopy.bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -512,7 +512,7 @@ describe('arc4.StaticArray', async () => { const staticArray = data.array() staticArray[0][0][0] = new Str('new value') - const sdkResult = data.abiType.encode(nativeValues) + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) const result = staticArray.bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -522,11 +522,11 @@ describe('arc4.StaticArray', async () => { const nativeValues = data.nativeValues() nativeValues[0][0][0] = 'new value' - const sdkEncodedBytes = data.abiType.encode(data.nativeValues()) + const sdkEncodedBytes = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const staticArray = data.create(Bytes(sdkEncodedBytes)) staticArray[0][0][0] = new Str('new value') - const sdkResult = data.abiType.encode(nativeValues) + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) const result = staticArray.bytes expect(result).toEqual(Bytes(sdkResult)) }) diff --git a/tests/arc4/static-bytes.spec.ts b/tests/arc4/static-bytes.spec.ts index ed71e3d..6d8cfca 100644 --- a/tests/arc4/static-bytes.spec.ts +++ b/tests/arc4/static-bytes.spec.ts @@ -1,13 +1,13 @@ +import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' import { Bytes } from '@algorandfoundation/algorand-typescript' import { interpretAsArc4, StaticBytes } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' -import { ABIType } from 'algosdk' import { describe, expect, test } from 'vitest' const testData = [ { - abiType() { - return ABIType.from(`byte[${this.nativeValue().length}]`) + abiTypeString() { + return `byte[${this.nativeValue().length}]` }, nativeValue() { return [0, 1, 8, 16, 32, 64, 128, 255, 20, 30, 40, 50, 111] @@ -17,8 +17,8 @@ const testData = [ }, }, { - abiType() { - return ABIType.from(`byte[${this.nativeValue().length}]`) + abiTypeString() { + return `byte[${this.nativeValue().length}]` }, nativeValue() { return encodingUtil.utf8ToUint8Array('01ff99aa'.repeat(8)) @@ -31,7 +31,7 @@ const testData = [ describe('arc4.StaticBytes', async () => { test.each(testData)('should be able to get bytes representation', async (data) => { - const sdkResult = data.abiType().encode(data.nativeValue()) + const sdkResult = getABIEncodedValue(data.nativeValue(), data.abiTypeString(), {}) const result = data.staticBytes().bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -47,7 +47,7 @@ describe('arc4.StaticBytes', async () => { test.each(testData)('create static bytes from bytes', async (data) => { const nativeValue = data.nativeValue() - const sdkEncodedBytes = data.abiType().encode(nativeValue) + const sdkEncodedBytes = getABIEncodedValue(nativeValue, data.abiTypeString(), {}) const result = interpretAsArc4(Bytes(sdkEncodedBytes)) for (let i = 0; i < result.length; i++) { expect(result[i].native).toEqual(nativeValue[i]) diff --git a/tests/arc4/struct.spec.ts b/tests/arc4/struct.spec.ts index a9f8137..64cdc04 100644 --- a/tests/arc4/struct.spec.ts +++ b/tests/arc4/struct.spec.ts @@ -1,7 +1,6 @@ +import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' import { Bytes, internal } from '@algorandfoundation/algorand-typescript' import { Bool, DynamicArray, interpretAsArc4, StaticArray, Str, Struct, Tuple, UintN } from '@algorandfoundation/algorand-typescript/arc4' -import { ABIType } from 'algosdk' - import { encodingUtil } from '@algorandfoundation/puya-ts' import { describe, expect, it, test } from 'vitest' import { AccountCls } from '../../src/impl/account' @@ -60,7 +59,7 @@ class Swapped6 extends Struct<{ const testData = [ { - abiType: ABIType.from('(uint64,bool,string,(uint64,bool,bool))'), + abiTypeString: '(uint64,bool,string,(uint64,bool,bool))', nativeValues() { return [nativeNumber, nativeBool, nativeString, [nativeNumber, nativeBool, nativeBool]] }, @@ -75,7 +74,7 @@ const testData = [ }, }, { - abiType: ABIType.from('(uint64,bool,string,((uint64,bool,bool),(uint64,bool,bool)))'), + abiTypeString: '(uint64,bool,string,((uint64,bool,bool),(uint64,bool,bool)))', nativeValues() { return [ nativeNumber, @@ -103,7 +102,7 @@ const testData = [ }, }, { - abiType: ABIType.from('(uint64,bool,string,(string[],string[],string,uint64,bool,uint64[3]))'), + abiTypeString: '(uint64,bool,string,(string[],string[],string,uint64,bool,uint64[3]))', nativeValues() { return [ nativeNumber, @@ -142,7 +141,7 @@ const testData = [ }, }, { - abiType: ABIType.from('(uint64,bool,string,((bool,string[],string),uint64,uint64[3]))'), + abiTypeString: '(uint64,bool,string,((bool,string[],string),uint64,uint64[3]))', nativeValues() { return [ nativeNumber, @@ -171,7 +170,7 @@ const testData = [ }, }, { - abiType: ABIType.from('(uint64,bool,string,((bool,string[],string),(uint64,uint64[3])))'), + abiTypeString: '(uint64,bool,string,((bool,string[],string),(uint64,uint64[3])))', nativeValues() { return [ nativeNumber, @@ -202,7 +201,7 @@ const testData = [ }, }, { - abiType: ABIType.from('(uint64,bool,string,((bool,(string[],string)),(uint64,uint64[3])))'), + abiTypeString: '(uint64,bool,string,((bool,(string[],string)),(uint64,uint64[3])))', nativeValues() { return [ nativeNumber, @@ -236,14 +235,14 @@ const testData = [ describe('arc4.Struct', async () => { test.each(testData)('should be able to get bytes representation', async (data) => { - const sdkResult = data.abiType.encode(data.nativeValues()) + const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.struct() expect(result.bytes).toEqual(sdkResult) }) test.each(testData)('create struct from bytes', async (data) => { const nativeValues = data.nativeValues() - const sdkResult = data.abiType.encode(nativeValues) + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) const result = data.create(Bytes(sdkResult)) let i = 0 @@ -261,7 +260,7 @@ 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 = data.abiType.encode(nativeValues) + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) const abiValues = data.struct() as Swapped6 abiValues.b = new UintN<64>(43) @@ -282,9 +281,9 @@ 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 = data.abiType.encode(nativeValues) + const sdkResult = getABIEncodedValue(nativeValues, data.abiTypeString, {}) - const bytes = Bytes(data.abiType.encode(data.nativeValues())) + 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 78e8627..d4cc2a4 100644 --- a/tests/arc4/tuple.spec.ts +++ b/tests/arc4/tuple.spec.ts @@ -1,8 +1,8 @@ +import { getABIEncodedValue } from '@algorandfoundation/algokit-utils/types/app-arc56' import { Bytes, internal } 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 { ABIType } from 'algosdk' import { afterEach, describe, expect, test } from 'vitest' import { AccountCls } from '../../src/impl/account' import { DeliberateAny } from '../../src/typescript-helpers' @@ -26,7 +26,7 @@ const otherAbiUint8 = new UintN<8>(42) const testData = [ { - abiType: ABIType.from('(uint8,bool,bool,address)'), + abiTypeString: '(uint8,bool,bool,address)', nativeValues() { return [nativeNumber, nativeBool, nativeBool, nativeAddress] }, @@ -41,7 +41,7 @@ const testData = [ }, }, { - abiType: ABIType.from('(string,uint8,bool)'), + abiTypeString: '(string,uint8,bool)', nativeValues() { return [nativeString, nativeNumber, nativeBool] }, @@ -56,7 +56,7 @@ const testData = [ }, }, { - abiType: ABIType.from('((uint8,bool,bool),(uint8,bool,bool))'), + abiTypeString: '((uint8,bool,bool),(uint8,bool,bool))', nativeValues() { return [ [nativeNumber, nativeBool, nativeBool], @@ -77,7 +77,7 @@ const testData = [ }, }, { - abiType: ABIType.from('(string[],string[],string,uint8,bool,uint8[3])'), + abiTypeString: '(string[],string[],string,uint8,bool,uint8[3])', nativeValues() { return [ [nativeString, nativeString], @@ -106,7 +106,7 @@ const testData = [ }, }, { - abiType: ABIType.from('((bool,string[],string),uint8,uint8[3])'), + abiTypeString: '((bool,string[],string),uint8,uint8[3])', nativeValues() { return [[nativeBool, [nativeString, nativeString], nativeString], nativeNumber, [nativeNumber, nativeNumber, nativeNumber]] }, @@ -125,7 +125,7 @@ const testData = [ }, }, { - abiType: ABIType.from('((bool,string[],string),(uint8,uint8[3]))'), + abiTypeString: '((bool,string[],string),(uint8,uint8[3]))', nativeValues() { return [ [nativeBool, [nativeString, nativeString], nativeString], @@ -146,7 +146,7 @@ const testData = [ }, }, { - abiType: ABIType.from('((bool,(string[],string,address)),(uint8,uint8[3]))'), + abiTypeString: '((bool,(string[],string,address)),(uint8,uint8[3]))', nativeValues() { return [ [nativeBool, [[nativeString, nativeString], nativeString, nativeAddress]], @@ -177,7 +177,7 @@ const testData = [ const testDataWithArray = [ { - abiType: ABIType.from('(string[],string[],string,uint8,bool,uint8[3])'), + abiTypeString: '(string[],string[],string,uint8,bool,uint8[3])', updatedNativeValues() { return [ [otherNativeString, nativeString, otherNativeString], @@ -211,7 +211,7 @@ const testDataWithArray = [ }, }, { - abiType: ABIType.from('((bool,string[],string),uint8,uint8[3])'), + abiTypeString: '((bool,string[],string),uint8,uint8[3])', updatedNativeValues() { return [ [nativeBool, [otherNativeString, nativeString, otherNativeString], nativeString], @@ -237,7 +237,7 @@ const testDataWithArray = [ }, }, { - abiType: ABIType.from('((bool,string[],string),(uint8,uint8[3]))'), + abiTypeString: '((bool,string[],string),(uint8,uint8[3]))', updatedNativeValues() { return [ [nativeBool, [otherNativeString, nativeString, otherNativeString], nativeString], @@ -261,7 +261,7 @@ const testDataWithArray = [ }, }, { - abiType: ABIType.from('((bool,(string[],string,address)),(uint8,uint8[3]))'), + abiTypeString: '((bool,(string[],string,address)),(uint8,uint8[3]))', updatedNativeValues() { return [ [nativeBool, [[otherNativeString, nativeString, otherNativeString], nativeString, nativeAddress]], @@ -298,7 +298,7 @@ describe('arc4.Tuple', async () => { }) test.each(testData)('should be able to get bytes representation', async (data) => { - const sdkResult = data.abiType.encode(data.nativeValues()) + const sdkResult = getABIEncodedValue(data.nativeValues(), data.abiTypeString, {}) const result = data.tuple().bytes expect(result).toEqual(Bytes(sdkResult)) }) @@ -314,7 +314,7 @@ describe('arc4.Tuple', async () => { test.each(testData)('create tuple from bytes', async (data) => { const nativeValues = data.nativeValues() - const sdkEncodedBytes = data.abiType.encode(nativeValues) + const sdkEncodedBytes = getABIEncodedValue(nativeValues, data.abiTypeString, {}) const result = data.create(Bytes(sdkEncodedBytes)) const tupleValues = result.native @@ -325,7 +325,7 @@ describe('arc4.Tuple', async () => { }) test.each(testDataWithArray)('update array values in tuple', async (data) => { - const sdkResult = data.abiType.encode(data.updatedNativeValues()) + const sdkResult = getABIEncodedValue(data.updatedNativeValues(), data.abiTypeString, {}) const tuple = data.tuple() data.update(tuple as DeliberateAny) const result = tuple.bytes diff --git a/tests/arc4/uintn.spec.ts b/tests/arc4/uintn.spec.ts index b3e8c77..a12eff7 100644 --- a/tests/arc4/uintn.spec.ts +++ b/tests/arc4/uintn.spec.ts @@ -43,8 +43,8 @@ describe('arc4.UintN', async () => { const result = new UintN32(value) - expect(result.native).toEqual(BigInt(expected)) - expect(avmResult).toEqual(BigInt(expected)) + expect(result.native).toEqual(expected) + expect(avmResult).toEqual(expected) }) test.each([ @@ -211,7 +211,7 @@ describe('arc4.UintN', async () => { const avmResult = await getAvmResult({ appClient }, 'verify_uintn_from_log', logValue) const result = interpretAsArc4>(Bytes(logValue), 'log') - expect(avmResult).toEqual(expected) + expect(BigInt(avmResult as number)).toEqual(expected) expect(result.native).toEqual(expected) }) diff --git a/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc56.json b/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc56.json new file mode 100644 index 0000000..13d7f43 --- /dev/null +++ b/tests/artifacts/crypto-ops/data/CryptoOpsContract.arc56.json @@ -0,0 +1,467 @@ +{ + "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/avm-invoker.ts b/tests/avm-invoker.ts index 4c6713a..b54e858 100644 --- a/tests/avm-invoker.ts +++ b/tests/avm-invoker.ts @@ -1,15 +1,16 @@ import * as algokit from '@algorandfoundation/algokit-utils' import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' -import { ABIAppCallArg, AppCallTransactionResult } from '@algorandfoundation/algokit-utils/types/app' -import { ApplicationClient } from '@algorandfoundation/algokit-utils/types/app-client' +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 { SendTransactionFrom, SendTransactionParams } from '@algorandfoundation/algokit-utils/types/transaction' import { Account, Bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' -import { ABIValue, generateAccount } from 'algosdk' import { randomUUID } from 'crypto' -import { asUint64, getRandomNumber, Lazy } from '../src/util' +import { Mutable } from '../src/typescript-helpers' +import { asUint64, getRandomBigInt, getRandomNumber, Lazy } from '../src/util' + +export type ABIValue = boolean | number | bigint | string | Uint8Array | ABIValue[] algokit.Config.configure({ logger: nullLogger }) @@ -23,52 +24,56 @@ export const getAlgorandAppClient = async (appSpec: AppSpec) => { } export const getAlgorandAppClientWithApp = async (appSpec: AppSpec) => { - const client = algorandClient() - const defaultSigner = await client.account.kmd.getLocalNetDispenserAccount() - const appClient = algokit.getAppClient({ app: appSpec, resolveBy: 'id', id: 0, sender: defaultSigner.account }, client.client.algod) - const app = await appClient.create({ note: randomUUID() }) - return [appClient, app] as const + 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 } const invokeMethod = async ( - appClient: ApplicationClient, + appClient: AppClient, method: string, - sendParams?: SendTransactionParams, - ...methodArgs: ABIAppCallArg[] -): Promise => { - const response = await appClient.call({ method, methodArgs, note: randomUUID(), sendParams }) - - if (response.return?.decodeError) { - throw response.return.decodeError - } + sendParams?: Partial[0]>, + ...methodArgs: ABIValue[] +): ReturnType => { + const response = await appClient.send.call({ method, args: methodArgs, note: randomUUID(), ...sendParams }) return response } export const getAvmResult = async ( - { appClient, sendParams }: { appClient: ApplicationClient; sendParams?: SendTransactionParams }, + { appClient, sendParams }: { appClient: AppClient; sendParams?: Partial[0]> }, method: string, - ...methodArgs: ABIAppCallArg[] + ...methodArgs: ABIValue[] ): Promise => { const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) - return result?.return?.returnValue as TResult + if (result.returns?.at(-1)?.decodeError) { + throw result.returns.at(-1)!.decodeError + } + return result?.return?.valueOf() as TResult } export const getAvmResultLog = async ( - { appClient, sendParams }: { appClient: ApplicationClient; sendParams?: SendTransactionParams }, + { appClient, sendParams }: { appClient: AppClient; sendParams?: Partial[0]> }, method: string, - ...methodArgs: ABIAppCallArg[] + ...methodArgs: ABIValue[] ): Promise => { const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) return result?.confirmation?.logs } export const getAvmResultRaw = async ( - { appClient, sendParams }: { appClient: ApplicationClient; sendParams?: SendTransactionParams }, + { appClient, sendParams }: { appClient: AppClient; sendParams?: Partial[0]> }, method: string, - ...methodArgs: ABIAppCallArg[] + ...methodArgs: ABIValue[] ): Promise => { const result = await invokeMethod(appClient, method, sendParams, ...methodArgs) - return result?.return?.rawReturnValue + return result?.returns?.at(-1)?.rawReturnValue } export const getLocalNetDefaultAccount = () => { @@ -77,66 +82,49 @@ export const getLocalNetDefaultAccount = () => { 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 = generateAccount() - - await algokit.ensureFunded( - { - accountToFund: account, - minSpendingBalance: AlgoAmount.MicroAlgos(INITIAL_BALANCE_MICRO_ALGOS), - }, - algorandClient().client.algod, - ) - return Account(Bytes.fromBase32(account.addr)) + // const account = generateAccount() + const account = await generateAVMTestAccount() + return Account(Bytes.fromBase32(account.addr.toString())) } -export const generateTestAsset = async (fields: { - creator: SendTransactionFrom - total?: number | bigint - decimals?: number - name?: string - unit?: string - url?: string - metadataHash?: string - manager?: SendTransactionFrom - reserveAccount?: SendTransactionFrom - freezeAccount?: SendTransactionFrom - clawbackAccount?: SendTransactionFrom - frozenByDefault?: boolean -}): Promise => { - const client = algorandClient() +export const generateTestAsset = async (fields: Mutable): Promise => { if (fields.total === undefined) { - fields.total = getRandomNumber(20, 120) + fields.total = getRandomBigInt(20, 120) } - if (fields.name === undefined) { - fields.name = `ASA ${getRandomNumber(1, 100)}_${getRandomNumber(1, 100)}_${fields.total}` + if (fields.assetName === undefined) { + fields.assetName = `ASA ${getRandomNumber(1, 100)}_${getRandomNumber(1, 100)}_${fields.total}` } if (fields.decimals === undefined) { fields.decimals = 0 } - const params = await client.getSuggestedParams() - const x = await algokit.createAsset( - { - creator: fields.creator, - total: BigInt(fields.total) * 10n ** BigInt(fields.decimals), - decimals: fields.decimals, - name: fields.name, - unit: fields.unit ?? '', - url: fields.url ?? 'https://algorand.co', - metadataHash: fields.metadataHash, - manager: fields.manager, - reserveAccount: fields.reserveAccount, - freezeAccount: fields.freezeAccount, - clawbackAccount: fields.clawbackAccount, - frozenByDefault: fields.frozenByDefault ?? false, - transactionParams: params, - note: randomUUID(), - }, - client.client.algod, - ) - if (x.confirmation === undefined) { + + const client = algorandClient() + const x = await client.send.assetCreate({ + sender: fields.sender, + total: BigInt(fields.total) * 10n ** BigInt(fields.decimals), + decimals: fields.decimals, + assetName: fields.assetName, + unitName: fields.unitName ?? '', + url: fields.url ?? 'https://algorand.co', + metadataHash: fields.metadataHash, + manager: fields.manager, + reserve: fields.reserve, + freeze: fields.freeze, + clawback: fields.clawback, + 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 09a4995..b6d98f1 100644 --- a/tests/crypto-op-codes.spec.ts +++ b/tests/crypto-op-codes.spec.ts @@ -1,16 +1,17 @@ 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 algosdk from 'algosdk' import { ec } from 'elliptic' import { keccak256 as js_keccak256 } from 'js-sha3' +import { sha512_256 as js_sha512_256 } from 'js-sha512' import nacl from 'tweetnacl' import { afterEach, describe, expect, it, Mock, test, vi } from 'vitest' import { TestExecutionContext } from '../src' -import { MAX_BYTES_SIZE } from '../src/constants' +import { LOGIC_DATA_PREFIX, MAX_BYTES_SIZE, PROGRAM_TAG } from '../src/constants' import * as op from '../src/impl/crypto' +import { conactUint8Arrays, decodePublicKey } from '../src/util' import appSpecJson from './artifacts/crypto-ops/data/CryptoOpsContract.arc32.json' -import { getAlgorandAppClientWithApp, getAvmResult } from './avm-invoker' +import { generateAVMTestAccount, getAlgorandAppClientWithApp, getAvmResult } from './avm-invoker' import { asUint8Array, getPaddedBytes } from './util' const MAX_ARG_LEN = 2048 @@ -99,7 +100,7 @@ describe('crypto op codes', async () => { const signature = nacl.sign.detached(asUint8Array(message), keyPair.secretKey) const avmResult = await getAvmResult( - { appClient, sendParams: { fee: AlgoAmount.Algos(2000) } }, + { appClient, sendParams: { staticFee: AlgoAmount.Algos(2000) } }, 'verify_ed25519verify_bare', asUint8Array(message), signature, @@ -112,18 +113,22 @@ describe('crypto op codes', async () => { describe('ed25519verify', async () => { it('should return true for valid signature', async () => { - const approval = app.compiledApproval + const approval = app.compiledApproval! const appCallTxn = ctx.any.txn.applicationCall({ approvalProgram: Bytes(approval.compiledBase64ToBytes), }) const message = Bytes('Test message for ed25519 verification') - const account = algosdk.generateAccount() - const publicKey = algosdk.decodeAddress(account.addr).publicKey - const signature = algosdk.tealSignFromProgram(account.sk, asUint8Array(message), approval.compiledBase64ToBytes) + const account = await generateAVMTestAccount() + const publicKey = decodePublicKey(account.addr.toString()) + const logicSig = conactUint8Arrays(asUint8Array(PROGRAM_TAG), approval.compiledBase64ToBytes) + const logicSigAddress = js_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 avmResult = await getAvmResult( - { appClient, sendParams: { fee: AlgoAmount.Algos(2000) } }, + { appClient, sendParams: { staticFee: AlgoAmount.Algos(2000) } }, 'verify_ed25519verify', asUint8Array(message), signature, @@ -149,7 +154,7 @@ describe('crypto op codes', async () => { const pubkeyY = Bytes.fromHex('48d0d337704fe2c675909d2c93f7995e199156f302f63c74a8b96827b28d777b') const avmResult = await getAvmResult( - { appClient, sendParams: { fee: AlgoAmount.Algos(5000) } }, + { appClient, sendParams: { staticFee: AlgoAmount.Algos(5000) } }, 'verify_ecdsa_verify_k1', asUint8Array(messageHash), asUint8Array(sigR), @@ -169,7 +174,7 @@ describe('crypto op codes', async () => { const pubkeyY = Bytes.fromHex('bd437b75d6f1db67155a95a0da4b41f2b6b3dc5d42f7db56238449e404a6c0a3') const avmResult = await getAvmResult( - { appClient, sendParams: { fee: AlgoAmount.Algos(5000) } }, + { appClient, sendParams: { staticFee: AlgoAmount.Algos(5000) } }, 'verify_ecdsa_verify_r1', asUint8Array(messageHash), asUint8Array(sigR), @@ -191,7 +196,7 @@ describe('crypto op codes', async () => { const c = testData.r const d = testData.s const avmResult = await getAvmResult( - { appClient, sendParams: { fee: AlgoAmount.Algos(5000) } }, + { appClient, sendParams: { staticFee: AlgoAmount.Algos(5000) } }, 'verify_ecdsa_recover_k1', asUint8Array(a), b.asNumber(), @@ -212,7 +217,7 @@ describe('crypto op codes', async () => { const d = testData.s await expect( getAvmResult( - { appClient, sendParams: { fee: AlgoAmount.Algos(5000) } }, + { appClient, sendParams: { staticFee: AlgoAmount.Algos(5000) } }, 'verify_ecdsa_recover_r1', asUint8Array(a), b.asNumber(), @@ -233,7 +238,7 @@ describe('crypto op codes', async () => { const keyPair = ecdsa.keyFromPublic(testData.pubkeyX.concat(testData.pubkeyY).asUint8Array()) const pubKeyArray = new Uint8Array(keyPair.getPublic(true, 'array')) const avmResult = await getAvmResult( - { appClient, sendParams: { fee: AlgoAmount.Algos(3000) } }, + { appClient, sendParams: { staticFee: AlgoAmount.Algos(3000) } }, 'verify_ecdsa_decompress_k1', pubKeyArray, ) @@ -257,7 +262,7 @@ describe('crypto op codes', async () => { it('should return mocked result', async () => { const avmResult = await getAvmResult<[Uint8Array, boolean]>( - { appClient, sendParams: { fee: AlgoAmount.Algos(6000) } }, + { appClient, sendParams: { staticFee: AlgoAmount.Algos(6000) } }, 'verify_vrf_verify', asUint8Array(a), asUint8Array(b), diff --git a/tests/global-state-arc4-values.spec.ts b/tests/global-state-arc4-values.spec.ts index e7900d3..9d35afb 100644 --- a/tests/global-state-arc4-values.spec.ts +++ b/tests/global-state-arc4-values.spec.ts @@ -20,7 +20,7 @@ import { asUint8Array } from './util' describe('ARC4 AppGlobal values', async () => { const appClient = await getAlgorandAppClient(arc4AppGlobalAppSpecJson as AppSpec) const localNetAccount = await getLocalNetDefaultAccount() - const defaultSenderAccountAddress = Bytes.fromBase32(localNetAccount.addr) + const defaultSenderAccountAddress = Bytes.fromBase32(localNetAccount.addr.toString()) const ctx = new TestExecutionContext(defaultSenderAccountAddress) afterEach(async () => { diff --git a/tests/local-state-arc4-values.spec.ts b/tests/local-state-arc4-values.spec.ts index c214378..f7d7848 100644 --- a/tests/local-state-arc4-values.spec.ts +++ b/tests/local-state-arc4-values.spec.ts @@ -1,4 +1,4 @@ -import { ApplicationClient } from '@algorandfoundation/algokit-utils/types/app-client' +import { AppClient } from '@algorandfoundation/algokit-utils/types/app-client' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { Account, Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' @@ -12,6 +12,7 @@ import { } 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 { OnApplicationComplete } from '../src/constants' import { DeliberateAny } from '../src/typescript-helpers' import { LocalStateContract } from './artifacts/state-ops/contract.algo' import arc4AppLocalAppSpecJson from './artifacts/state-ops/data/LocalStateContract.arc32.json' @@ -20,7 +21,7 @@ import { getAlgorandAppClient, getAvmResult, getLocalNetDefaultAccount } from '. describe('ARC4 AppLocal values', async () => { const appClient = await getAlgorandAppClient(arc4AppLocalAppSpecJson as AppSpec) const localNetAccount = await getLocalNetDefaultAccount() - const defaultSenderAccountAddress = Bytes.fromBase32(localNetAccount.addr) + const defaultSenderAccountAddress = Bytes.fromBase32(localNetAccount.addr.toString()) const ctx = new TestExecutionContext(defaultSenderAccountAddress) await tryOptIn(appClient) @@ -92,16 +93,16 @@ 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) + const avmResult = await getAvmResult({ appClient }, data.methodName, localNetAccount.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: ApplicationClient) => { +const tryOptIn = async (client: AppClient) => { try { - await client.optIn({ method: 'opt_in', methodArgs: [] }) + await client.send.call({ method: 'opt_in', args: [], onComplete: OnApplicationComplete.OptInOC }) } catch (e) { if (!(e as DeliberateAny).message.includes('has already opted in to app')) { throw e diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 8bbeea6..938c6fb 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -1,11 +1,11 @@ import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' -import { ApplicationClient } from '@algorandfoundation/algokit-utils/types/app-client' +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 { DynamicBytes, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' -import { ABI_RETURN_VALUE_LOG_PREFIX, MIN_TXN_FEE, ZERO_ADDRESS } from '../src/constants' +import { ABI_RETURN_VALUE_LOG_PREFIX, MIN_TXN_FEE, OnApplicationComplete, ZERO_ADDRESS } from '../src/constants' import { testInvariant } from '../src/errors' import { Block, gloadBytes, gloadUint64 } from '../src/impl' import { AccountCls } from '../src/impl/account' @@ -87,7 +87,7 @@ describe('State op codes', async () => { }) const avmResult = await getAvmResult( - { appClient, sendParams: { fee: AlgoAmount.Algos(1000) } }, + { appClient, sendParams: { staticFee: AlgoAmount.Algos(1000) } }, methodName, asUint8Array(dummyAccount.bytes), ) @@ -116,16 +116,16 @@ describe('State op codes', async () => { ])('%s should return %s', async (methodName, expectedValue) => { const application = ctx.any.application({ applicationId: app.appId, - approvalProgram: Bytes(app.compiledApproval.compiledBase64ToBytes), - clearStateProgram: Bytes(app.compiledClear.compiledBase64ToBytes), + 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)), + creator: Account(Bytes.fromBase32(dummyAccount.addr.toString())), }) - const avmResult = await getAvmResult({ appClient, sendParams: { fee: AlgoAmount.Algos(1000) } }, methodName, app.appId) + const avmResult = await getAvmResult({ appClient, sendParams: { staticFee: AlgoAmount.Algos(1000) } }, methodName, app.appId) const mockContract = ctx.contract.create(StateAppParamsContract) const mockResult = mockContract[methodName as keyof StateAppParamsContract](application) @@ -150,12 +150,12 @@ describe('State op codes', async () => { ['verify_asset_frozen_get', false], ])('should return the correct field value of the asset holding', async (methodName, expectedValue) => { const dummyAsset = await generateTestAsset({ - creator: dummyAccount, - total: 100, + sender: dummyAccount.addr, + total: 100n, decimals: 0, - frozenByDefault: false, + defaultFrozen: false, }) - const avmResult = await getAvmResult({ appClient }, methodName, dummyAccount.addr, asBigInt(dummyAsset)) + const avmResult = await getAvmResult({ appClient }, methodName, dummyAccount.addr.toString(), asBigInt(dummyAsset)) const mockAsset = ctx.any.asset() const mockAccount = ctx.any.account({ @@ -192,7 +192,7 @@ describe('State op codes', async () => { ['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)) + const creator = Account(Bytes.fromBase32(dummyAccount.addr.toString())) const metadataHash = Bytes(`test${' '.repeat(28)}`) const mockAsset = ctx.any.asset({ total: Uint64(100), @@ -205,12 +205,12 @@ describe('State op codes', async () => { }) const dummyAsset = await generateTestAsset({ - creator: dummyAccount, - total: 100, + sender: dummyAccount.addr, + total: 100n, decimals: 0, - frozenByDefault: false, - name: 'TEST', - unit: 'UNIT', + defaultFrozen: false, + assetName: 'TEST', + unitName: 'UNIT', url: 'https://algorand.co', metadataHash: metadataHash.toString(), }) @@ -518,23 +518,34 @@ describe('State op codes', async () => { it('should be able to put, get and delete app local state', async () => { const localNetAccount = await getLocalNetDefaultAccount() - const account = Account(Bytes.fromBase32(localNetAccount.addr)) + const account = Account(Bytes.fromBase32(localNetAccount.addr.toString())) const bytesKey = 'local_bytes' const uint64Key = 'local_uint64' const bytesValue = 'test_bytes' const uint64Value = 42 // put - await getAvmResult({ appClient }, 'verify_put_bytes', localNetAccount.addr, asUint8Array(bytesKey), asUint8Array(bytesValue)) - await getAvmResult({ appClient }, 'verify_put_uint64', localNetAccount.addr, asUint8Array(uint64Key), uint64Value) + await getAvmResult( + { appClient }, + 'verify_put_bytes', + localNetAccount.addr.toString(), + asUint8Array(bytesKey), + asUint8Array(bytesValue), + ) + await getAvmResult({ appClient }, 'verify_put_uint64', localNetAccount.addr.toString(), asUint8Array(uint64Key), uint64Value) const contract = ctx.contract.create(StateAppLocalContract) contract.verify_put_bytes(account, Bytes(bytesKey), Bytes(bytesValue)) contract.verify_put_uint64(account, Bytes(uint64Key), Uint64(uint64Value)) // get - const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_bytes', localNetAccount.addr, asUint8Array(bytesKey)) - const uint64AvmResult = await getAvmResult({ appClient }, 'verify_get_uint64', localNetAccount.addr, asUint8Array(uint64Key)) + const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_bytes', localNetAccount.addr.toString(), asUint8Array(bytesKey)) + const uint64AvmResult = await getAvmResult( + { appClient }, + 'verify_get_uint64', + localNetAccount.addr.toString(), + asUint8Array(uint64Key), + ) const bytesResult = contract.verify_get_bytes(account, Bytes(bytesKey)) const uint64Result = contract.verify_get_uint64(account, Bytes(uint64Key)) @@ -542,15 +553,22 @@ describe('State op codes', async () => { expect(asBigInt(uint64Result)).toEqual(uint64AvmResult) // delete - await getAvmResult({ appClient }, 'verify_delete', localNetAccount.addr, asUint8Array(bytesKey)) - await getAvmResult({ appClient }, 'verify_delete', localNetAccount.addr, asUint8Array(uint64Key)) + await getAvmResult({ appClient }, 'verify_delete', localNetAccount.addr.toString(), asUint8Array(bytesKey)) + await getAvmResult({ appClient }, 'verify_delete', localNetAccount.addr.toString(), asUint8Array(uint64Key)) contract.verify_delete(account, Bytes(bytesKey)) contract.verify_delete(account, Bytes(uint64Key)) - await expect(() => getAvmResult({ appClient }, 'verify_get_bytes', localNetAccount.addr, asUint8Array(bytesKey))).rejects.toThrow() + await expect(() => + getAvmResult({ appClient }, 'verify_get_bytes', localNetAccount.addr.toString(), asUint8Array(bytesKey)), + ).rejects.toThrow() expect(() => contract.verify_get_bytes(account, Bytes(bytesKey))).toThrow('value is not set') - const uint64AvmResult2 = await getAvmResult({ appClient }, 'verify_get_uint64', localNetAccount.addr, asUint8Array(uint64Key)) + const uint64AvmResult2 = await getAvmResult( + { appClient }, + 'verify_get_uint64', + localNetAccount.addr.toString(), + asUint8Array(uint64Key), + ) const uint64Result2 = contract.verify_get_uint64(account, Bytes(uint64Key)) expect(asBigInt(uint64Result2)).toEqual(uint64AvmResult2) }) @@ -558,13 +576,19 @@ describe('State op codes', async () => { it('should be able to use _ex methods to get state of another app', async () => { const key = 'local_bytes' const localNetAccount = await getLocalNetDefaultAccount() - const account = Account(Bytes.fromBase32(localNetAccount.addr)) + const account = Account(Bytes.fromBase32(localNetAccount.addr.toString())) const secondContract = ctx.contract.create(StateAppLocalExContract) const secondApp = ctx.ledger.getApplicationForContract(secondContract) expect(secondApp.localNumUint.valueOf()).toEqual(1) expect(secondApp.localNumBytes.valueOf()).toEqual(2) - const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_ex_bytes', localNetAccount.addr, exApp.appId, asUint8Array(key)) + const bytesAvmResult = await getAvmResult( + { appClient }, + 'verify_get_ex_bytes', + localNetAccount.addr.toString(), + exApp.appId, + asUint8Array(key), + ) const contract = ctx.contract.create(StateAppLocalContract) secondContract.localBytes(account).value = Bytes('dummy_bytes_from_external_contract') @@ -576,13 +600,19 @@ describe('State op codes', async () => { it('should be able to use _ex methods to get arc4 state values of another app', async () => { const key = 'local_arc4_bytes' const localNetAccount = await getLocalNetDefaultAccount() - const account = Account(Bytes.fromBase32(localNetAccount.addr)) + const account = Account(Bytes.fromBase32(localNetAccount.addr.toString())) const secondContract = ctx.contract.create(StateAppLocalExContract) const secondApp = ctx.ledger.getApplicationForContract(secondContract) expect(secondApp.localNumUint.valueOf()).toEqual(1) expect(secondApp.localNumBytes.valueOf()).toEqual(2) - const bytesAvmResult = await getAvmResult({ appClient }, 'verify_get_ex_bytes', localNetAccount.addr, exApp.appId, asUint8Array(key)) + const bytesAvmResult = await getAvmResult( + { appClient }, + 'verify_get_ex_bytes', + localNetAccount.addr.toString(), + exApp.appId, + asUint8Array(key), + ) const contract = ctx.contract.create(StateAppLocalContract) secondContract.localArc4Bytes(account).value = new DynamicBytes('dummy_arc4_bytes') @@ -592,9 +622,9 @@ describe('State op codes', async () => { }) }) }) -const tryOptIn = async (client: ApplicationClient) => { +const tryOptIn = async (client: AppClient) => { try { - await client.optIn({ method: 'opt_in', methodArgs: [] }) + await client.send.call({ method: 'opt_in', args: [], onComplete: OnApplicationComplete.OptInOC }) } catch (e) { if (!(e as DeliberateAny).message.includes('has already opted in to app')) { throw e diff --git a/tests/util.ts b/tests/util.ts index bffce72..ae307dc 100644 --- a/tests/util.ts +++ b/tests/util.ts @@ -1,6 +1,6 @@ import { Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' -import { ABIValue } from 'algosdk' import { createHash } from 'crypto' +import type { ABIValue } from './avm-invoker' export const padUint8Array = (arr: Uint8Array, padSize: number): Uint8Array => { const paddedUint8Array = new Uint8Array(arr.length + padSize) From 2084c958d4430178d3f2018ea3f339f00349e041 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Wed, 18 Dec 2024 21:52:13 +0800 Subject: [PATCH 71/85] feat: implement stubs for LogicSig and arg, len op codes --- examples/htlc-logicsig/signature.algo.ts | 39 + examples/htlc-logicsig/signature.spec.ts | 32 + package-lock.json | 1 + src/impl/index.ts | 7 +- src/impl/logicSigArg.ts | 8 + src/impl/pure.ts | 6 +- src/runtime-helpers.ts | 13 + src/test-execution-context.ts | 17 +- .../miscellaneous-ops/contract.algo.ts | 7 + .../MiscellaneousOpsContract.approval.teal | 407 ++++--- .../data/MiscellaneousOpsContract.arc32.json | 24 +- .../data/MiscellaneousOpsContract.arc56.json | 1024 +++++++++++++++++ tests/pure-op-codes.spec.ts | 18 + 13 files changed, 1416 insertions(+), 187 deletions(-) create mode 100644 examples/htlc-logicsig/signature.algo.ts create mode 100644 examples/htlc-logicsig/signature.spec.ts create mode 100644 src/impl/logicSigArg.ts create mode 100644 tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc56.json diff --git a/examples/htlc-logicsig/signature.algo.ts b/examples/htlc-logicsig/signature.algo.ts new file mode 100644 index 0000000..df6cf1f --- /dev/null +++ b/examples/htlc-logicsig/signature.algo.ts @@ -0,0 +1,39 @@ +import { Account, Bytes, Global, LogicSig, op, TransactionType, Txn, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import algosdk from 'algosdk' + +export default class HashedTimeLockedLogicSig extends LogicSig { + program(): boolean | uint64 { + // Participants + const sellerAddress = Bytes(algosdk.decodeAddress('6ZHGHH5Z5CTPCF5WCESXMGRSVK7QJETR63M3NY5FJCUYDHO57VTCMJOBGY').publicKey) + const buyerAddress = Bytes(algosdk.decodeAddress('7Z5PWO2C6LFNQFGHWKSK5H47IQP5OJW2M3HA2QPXTY3WTNP5NU2MHBW27M').publicKey) + const seller = Account(sellerAddress) + const buyer = Account(buyerAddress) + + // Contract parameters + const feeLimit = Uint64(1000) + const secretHash = Bytes.fromHex('2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b') + const timeout = Uint64(3000) + + // Transaction conditions + const isPayment = Txn.typeEnum === TransactionType.Payment + const isFeeAcceptable = Txn.fee < feeLimit + const isNoCloseTo = Txn.closeRemainderTo === Global.zeroAddress + const isNoRekey = Txn.rekeyTo === Global.zeroAddress + + // Safety conditions + const safetyConditions = isPayment && isNoCloseTo && isNoRekey + + // Seller receives payment if correct secret is provided + const isToSeller = Txn.receiver === seller + const isSecretCorrect = op.sha256(op.arg(0)) === secretHash + const sellerReceives = isToSeller && isSecretCorrect + + // Buyer receives refund after timeout + const isToBuyer = Txn.receiver === buyer + const isAfterTimeout = Txn.firstValid > timeout + const buyerReceivesRefund = isToBuyer && isAfterTimeout + + // Final contract logic + return isFeeAcceptable && safetyConditions && (sellerReceives || buyerReceivesRefund) + } +} diff --git a/examples/htlc-logicsig/signature.spec.ts b/examples/htlc-logicsig/signature.spec.ts new file mode 100644 index 0000000..2224f10 --- /dev/null +++ b/examples/htlc-logicsig/signature.spec.ts @@ -0,0 +1,32 @@ +import { Account, Bytes } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import algosdk from 'algosdk' +import { afterEach, describe, expect, it } from 'vitest' +import { ZERO_ADDRESS } from '../../src/constants' +import HashedTimeLockedLogicSig from './signature.algo' + +describe('HTLC LogicSig', () => { + const ctx = new TestExecutionContext() + + afterEach(() => { + ctx.reset() + }) + + it('seller receives payment if correct secret is provided', () => { + const receiverAddress = Bytes(algosdk.decodeAddress('6ZHGHH5Z5CTPCF5WCESXMGRSVK7QJETR63M3NY5FJCUYDHO57VTCMJOBGY').publicKey) + ctx.txn + .createScope([ + ctx.any.txn.payment({ + fee: 500, + firstValid: 1000, + closeRemainderTo: Account(ZERO_ADDRESS), + rekeyTo: Account(ZERO_ADDRESS), + receiver: Account(receiverAddress), + }), + ]) + .execute(() => { + const result = ctx.executeLogicSig(new HashedTimeLockedLogicSig(), Bytes('secret')) + expect(result).toBe(true) + }) + }) +}) diff --git a/package-lock.json b/package-lock.json index b96dcaf..793bb2c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13262,6 +13262,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/src/impl/index.ts b/src/impl/index.ts index 159e731..2909910 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -4,12 +4,13 @@ export { AppLocal } from './app-local' export { AppParams } from './app-params' export { AssetHolding } from './asset-holding' export { AssetParams } from './asset-params' +export { Block } from './block' export { Box } from './box' export * from './crypto' export { Global } from './global' export { GTxn } from './gtxn' export { GITxn, ITxn, ITxnCreate } from './itxn' +export { arg } from './logicSigArg' export * from './pure' -export { Scratch, gloadBytes, gloadUint64 } from './scratch' -export { Block } from './block' -export { Txn, gaid } from './txn' +export { gloadBytes, gloadUint64, Scratch } from './scratch' +export { gaid, Txn } from './txn' diff --git a/src/impl/logicSigArg.ts b/src/impl/logicSigArg.ts new file mode 100644 index 0000000..6d411fc --- /dev/null +++ b/src/impl/logicSigArg.ts @@ -0,0 +1,8 @@ +import { bytes, internal } from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' +import { asNumber } from '../util' + +export const arg = (a: internal.primitives.StubUint64Compat): bytes => { + const index = asNumber(a) + return lazyContext.value.activeLogicSigArgs[index] +} diff --git a/src/impl/pure.ts b/src/impl/pure.ts index 6d655f7..c81a94b 100644 --- a/src/impl/pure.ts +++ b/src/impl/pure.ts @@ -1,7 +1,7 @@ import { Base64, biguint, Bytes, bytes, internal, Uint64, uint64 } 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 { asBigUint, asBytes, asMaybeBytesCls, asMaybeUint64Cls, asUint64Cls, binaryStringToBytes } from '../util' +import { asBigUint, asBytes, asBytesCls, asMaybeBytesCls, asMaybeUint64Cls, asUint64Cls, binaryStringToBytes } from '../util' export const addw = (a: internal.primitives.StubUint64Compat, b: internal.primitives.StubUint64Compat): readonly [uint64, uint64] => { const uint64A = internal.primitives.Uint64Cls.fromCompat(a) @@ -172,6 +172,10 @@ export const itob = (a: internal.primitives.StubUint64Compat): bytes => { return asUint64Cls(a).toBytes().asAlgoTs() } +export const len = (a: internal.primitives.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) diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 5671a7e..10e58cc 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -2,6 +2,7 @@ import { internal } from '@algorandfoundation/algorand-typescript' import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' import { MAX_UINT64 } from './constants' import type { TypeInfo } from './encoders' +import { AccountCls } from './impl/account' import { DeliberateAny } from './typescript-helpers' import { nameOfType } from './util' @@ -37,6 +38,9 @@ export function binaryOp(left: unknown, right: unknown, op: BinaryOps) { if (left instanceof ARC4Encoded && right instanceof ARC4Encoded) { return arc4EncodedOp(left, right, op) } + if (left instanceof AccountCls && right instanceof AccountCls) { + return accountBinaryOp(left, right, op) + } if (left instanceof internal.primitives.BigUintCls || right instanceof internal.primitives.BigUintCls) { return bigUintBinaryOp(left, right, op) } @@ -84,6 +88,15 @@ function arc4EncodedOp(left: ARC4Encoded, right: ARC4Encoded, op: BinaryOps): De internal.errors.internalError(`Unsupported operator ${op}`) } } + +function accountBinaryOp(left: AccountCls, right: AccountCls, op: BinaryOps): DeliberateAny { + switch (op) { + case '===': + return bytesBinaryOp(left.bytes, right.bytes, op) + default: + internal.errors.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() diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index f86e183..c7723c4 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -1,4 +1,4 @@ -import { Account, Application, Asset, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, Application, Asset, Bytes, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { captureMethodConfig } from './abi-metadata' import { DecodedLogs, LogDecoding } from './decode-logs' import * as ops from './impl' @@ -27,6 +27,7 @@ export class TestExecutionContext implements internal.ExecutionContext { #txnContext: TransactionContext #valueGenerator: ValueGenerator #defaultSender: Account + #activeLogicSigArgs: bytes[] constructor(defaultSenderAddress?: bytes) { internal.ctxMgr.instance = this @@ -35,6 +36,7 @@ export class TestExecutionContext implements internal.ExecutionContext { this.#txnContext = new TransactionContext() this.#valueGenerator = new ValueGenerator() this.#defaultSender = Account(defaultSenderAddress ?? getRandomBytes(32).asAlgoTs()) + this.#activeLogicSigArgs = [] } account(address?: bytes): Account { @@ -120,6 +122,19 @@ export class TestExecutionContext implements internal.ExecutionContext { } } + get activeLogicSigArgs(): bytes[] { + return this.#activeLogicSigArgs + } + + executeLogicSig(logicSig: LogicSig, ...args: bytes[]): boolean | uint64 { + this.#activeLogicSigArgs = args + try { + return logicSig.program() + } finally { + this.#activeLogicSigArgs = [] + } + } + reset() { this.#contractContext = new ContractContext() this.#ledgerContext = new LedgerContext() diff --git a/tests/artifacts/miscellaneous-ops/contract.algo.ts b/tests/artifacts/miscellaneous-ops/contract.algo.ts index 0caefed..9876d85 100644 --- a/tests/artifacts/miscellaneous-ops/contract.algo.ts +++ b/tests/artifacts/miscellaneous-ops/contract.algo.ts @@ -144,6 +144,13 @@ export class MiscellaneousOpsContract extends arc4.Contract { return result } + @arc4.abimethod() + public verify_bytes_len(a: bytes, pad_a_size: uint64): uint64 { + const paddedA = op.bzero(pad_a_size).concat(a) + const result = op.len(paddedA) + return result + } + @arc4.abimethod() public verify_mulw(a: uint64, b: uint64): readonly [uint64, uint64] { const result = op.mulw(a, b) diff --git a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal index 2fb67ab..a53da57 100644 --- a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal +++ b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.approval.teal @@ -13,10 +13,10 @@ __puya_arc4_router__: // export class MiscellaneousOpsContract extends arc4.Contract { proto 0 1 txn NumAppArgs - bz __puya_arc4_router___bare_routing@38 - pushbytess 0x45847eea 0xf57aceb5 0x7d631730 0xa1b24441 0xcd7be1ac 0x7cfda64b 0x54a910d9 0xc46568de 0x7a46a6ae 0x04372209 0x7e5f6d72 0x24ebcf84 0x9c0b3397 0x0ad40da4 0x95178870 0xdeedc99b 0xab2150bb 0x02a54017 0x3db66b41 0xc7ea8c2a 0x1dcea50c 0x16166f9a 0x2f472065 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_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[]" + 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_mulw_route@25 __puya_arc4_router___verify_replace_route@26 __puya_arc4_router___verify_select_bytes_route@27 __puya_arc4_router___verify_select_uint64_route@28 __puya_arc4_router___verify_setbit_bytes_route@29 __puya_arc4_router___verify_setbit_uint64_route@30 __puya_arc4_router___verify_setbyte_route@31 __puya_arc4_router___verify_shl_route@32 __puya_arc4_router___verify_shr_route@33 __puya_arc4_router___verify_sqrt_route@34 __puya_arc4_router___verify_substring_route@35 + 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 @@ -25,9 +25,9 @@ __puya_arc4_router___verify_addw_route@2: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -54,9 +54,9 @@ __puya_arc4_router___verify_base64_decode_standard_route@3: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -82,9 +82,9 @@ __puya_arc4_router___verify_base64_decode_url_route@4: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -110,9 +110,9 @@ __puya_arc4_router___verify_bytes_bitlen_route@5: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -135,9 +135,9 @@ __puya_arc4_router___verify_uint64_bitlen_route@6: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -158,9 +158,9 @@ __puya_arc4_router___verify_bsqrt_route@7: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -186,9 +186,9 @@ __puya_arc4_router___verify_btoi_route@8: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -209,9 +209,9 @@ __puya_arc4_router___verify_bzero_route@9: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -237,9 +237,9 @@ __puya_arc4_router___verify_concat_route@10: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -271,9 +271,9 @@ __puya_arc4_router___verify_divmodw_route@11: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -314,9 +314,9 @@ __puya_arc4_router___verify_divw_route@12: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -341,9 +341,9 @@ __puya_arc4_router___verify_err_route@13: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating callsub verify_err intc_0 // 1 retsub @@ -353,9 +353,9 @@ __puya_arc4_router___verify_exp_route@14: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -378,9 +378,9 @@ __puya_arc4_router___verify_expw_route@15: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -407,9 +407,9 @@ __puya_arc4_router___verify_extract_route@16: // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -435,18 +435,18 @@ __puya_arc4_router___verify_extract_route@16: retsub __puya_arc4_router___verify_extract_from_2_route@17: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:98 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:99 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:98 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:99 // @arc4.abimethod() callsub verify_extract_from_2 dup @@ -463,20 +463,20 @@ __puya_arc4_router___verify_extract_from_2_route@17: retsub __puya_arc4_router___verify_extract_uint16_route@18: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:104 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:105 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:104 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:105 // @arc4.abimethod() callsub verify_extract_uint16 itob @@ -488,20 +488,20 @@ __puya_arc4_router___verify_extract_uint16_route@18: retsub __puya_arc4_router___verify_extract_uint32_route@19: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:110 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:111 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:110 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:111 // @arc4.abimethod() callsub verify_extract_uint32 itob @@ -513,20 +513,20 @@ __puya_arc4_router___verify_extract_uint32_route@19: retsub __puya_arc4_router___verify_extract_uint64_route@20: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:116 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:117 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:116 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:117 // @arc4.abimethod() callsub verify_extract_uint64 itob @@ -538,20 +538,20 @@ __puya_arc4_router___verify_extract_uint64_route@20: retsub __puya_arc4_router___verify_getbit_bytes_route@21: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:122 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:123 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:122 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:123 // @arc4.abimethod() callsub verify_getbit_bytes itob @@ -563,20 +563,20 @@ __puya_arc4_router___verify_getbit_bytes_route@21: retsub __puya_arc4_router___verify_getbit_uint64_route@22: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:128 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:129 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:128 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:129 // @arc4.abimethod() callsub verify_getbit_uint64 itob @@ -588,20 +588,20 @@ __puya_arc4_router___verify_getbit_uint64_route@22: retsub __puya_arc4_router___verify_getbyte_route@23: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:134 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:135 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:134 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:135 // @arc4.abimethod() callsub verify_getbyte itob @@ -613,18 +613,18 @@ __puya_arc4_router___verify_getbyte_route@23: retsub __puya_arc4_router___verify_itob_route@24: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:140 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:141 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:140 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:141 // @arc4.abimethod() callsub verify_itob dup @@ -640,21 +640,46 @@ __puya_arc4_router___verify_itob_route@24: intc_0 // 1 retsub -__puya_arc4_router___verify_mulw_route@25: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:146 +__puya_arc4_router___verify_bytes_len_route@25: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:147 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:146 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:154 // @arc4.abimethod() callsub verify_mulw swap @@ -669,14 +694,14 @@ __puya_arc4_router___verify_mulw_route@25: intc_0 // 1 retsub -__puya_arc4_router___verify_replace_route@26: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:152 +__puya_arc4_router___verify_replace_route@27: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:160 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -685,7 +710,7 @@ __puya_arc4_router___verify_replace_route@26: btoi txna ApplicationArgs 3 extract 2 0 - // tests/artifacts/miscellaneous-ops/contract.algo.ts:152 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:160 // @arc4.abimethod() callsub verify_replace dup @@ -701,14 +726,14 @@ __puya_arc4_router___verify_replace_route@26: intc_0 // 1 retsub -__puya_arc4_router___verify_select_bytes_route@27: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:158 +__puya_arc4_router___verify_select_bytes_route@28: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:166 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -717,7 +742,7 @@ __puya_arc4_router___verify_select_bytes_route@27: extract 2 0 txna ApplicationArgs 3 btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:158 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:166 // @arc4.abimethod() callsub verify_select_bytes dup @@ -733,14 +758,14 @@ __puya_arc4_router___verify_select_bytes_route@27: intc_0 // 1 retsub -__puya_arc4_router___verify_select_uint64_route@28: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:164 +__puya_arc4_router___verify_select_uint64_route@29: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:172 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -749,7 +774,7 @@ __puya_arc4_router___verify_select_uint64_route@28: btoi txna ApplicationArgs 3 btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:164 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:172 // @arc4.abimethod() callsub verify_select_uint64 itob @@ -760,14 +785,14 @@ __puya_arc4_router___verify_select_uint64_route@28: intc_0 // 1 retsub -__puya_arc4_router___verify_setbit_bytes_route@29: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:170 +__puya_arc4_router___verify_setbit_bytes_route@30: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:178 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -776,7 +801,7 @@ __puya_arc4_router___verify_setbit_bytes_route@29: btoi txna ApplicationArgs 3 btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:170 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:178 // @arc4.abimethod() callsub verify_setbit_bytes dup @@ -792,14 +817,14 @@ __puya_arc4_router___verify_setbit_bytes_route@29: intc_0 // 1 retsub -__puya_arc4_router___verify_setbit_uint64_route@30: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:176 +__puya_arc4_router___verify_setbit_uint64_route@31: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:184 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -808,7 +833,7 @@ __puya_arc4_router___verify_setbit_uint64_route@30: btoi txna ApplicationArgs 3 btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:176 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:184 // @arc4.abimethod() callsub verify_setbit_uint64 itob @@ -819,14 +844,14 @@ __puya_arc4_router___verify_setbit_uint64_route@30: intc_0 // 1 retsub -__puya_arc4_router___verify_setbyte_route@31: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:182 +__puya_arc4_router___verify_setbyte_route@32: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:190 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -835,7 +860,7 @@ __puya_arc4_router___verify_setbyte_route@31: btoi txna ApplicationArgs 3 btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:182 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:190 // @arc4.abimethod() callsub verify_setbyte dup @@ -851,21 +876,21 @@ __puya_arc4_router___verify_setbyte_route@31: intc_0 // 1 retsub -__puya_arc4_router___verify_shl_route@32: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:188 +__puya_arc4_router___verify_shl_route@33: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:196 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:188 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:196 // @arc4.abimethod() callsub verify_shl itob @@ -876,21 +901,21 @@ __puya_arc4_router___verify_shl_route@32: intc_0 // 1 retsub -__puya_arc4_router___verify_shr_route@33: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:194 +__puya_arc4_router___verify_shr_route@34: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:202 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:194 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:202 // @arc4.abimethod() callsub verify_shr itob @@ -901,19 +926,19 @@ __puya_arc4_router___verify_shr_route@33: intc_0 // 1 retsub -__puya_arc4_router___verify_sqrt_route@34: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:200 +__puya_arc4_router___verify_sqrt_route@35: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:208 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + 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:200 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:208 // @arc4.abimethod() callsub verify_sqrt itob @@ -924,14 +949,14 @@ __puya_arc4_router___verify_sqrt_route@34: intc_0 // 1 retsub -__puya_arc4_router___verify_substring_route@35: - // tests/artifacts/miscellaneous-ops/contract.algo.ts:206 +__puya_arc4_router___verify_substring_route@36: + // tests/artifacts/miscellaneous-ops/contract.algo.ts:214 // @arc4.abimethod() txn OnCompletion ! - assert // OnCompletion is NoOp + assert // OnCompletion is not NoOp txn ApplicationID - assert // is not creating + assert // can only call when not creating // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { txna ApplicationArgs 1 @@ -940,7 +965,7 @@ __puya_arc4_router___verify_substring_route@35: btoi txna ApplicationArgs 3 btoi - // tests/artifacts/miscellaneous-ops/contract.algo.ts:206 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:214 // @arc4.abimethod() callsub verify_substring dup @@ -956,18 +981,18 @@ __puya_arc4_router___verify_substring_route@35: intc_0 // 1 retsub -__puya_arc4_router___bare_routing@38: +__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@42 + bnz __puya_arc4_router___after_if_else@43 txn ApplicationID ! - assert // is creating + assert // can only call when creating intc_0 // 1 retsub -__puya_arc4_router___after_if_else@42: +__puya_arc4_router___after_if_else@43: // tests/artifacts/miscellaneous-ops/contract.algo.ts:3 // export class MiscellaneousOpsContract extends arc4.Contract { intc_1 // 0 @@ -1227,307 +1252,327 @@ verify_extract: // 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:98-99 + // 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:100 + // 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:101 + // 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:104-105 + // 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:106 + // 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:107 + // 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:110-111 + // 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:112 + // 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:113 + // 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:116-117 + // 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:118 + // 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:119 + // 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:122-123 + // 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:124 + // 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:125 + // 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:128-129 + // 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:130 + // 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:131 + // 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:134-135 + // 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:136 + // 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:137 + // 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:140-141 + // 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:142 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:143 // const result = op.itob(a) frame_dig -1 itob - // tests/artifacts/miscellaneous-ops/contract.algo.ts:143 + // 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:146-147 + // 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:148 + // 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:149 + // 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:152-153 + // 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:154 + // 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:155 + // 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:158-159 + // 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:160 + // 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:161 + // 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:164-165 + // 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:166 + // 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:167 + // 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:170-171 + // 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:172 + // 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:173 + // 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:176-177 + // 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:178 + // 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:179 + // 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:182-183 + // 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:184 + // 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:185 + // 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:188-189 + // 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:190 + // 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:191 + // 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:194-195 + // 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:196 + // 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:197 + // 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:200-201 + // 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:202 + // tests/artifacts/miscellaneous-ops/contract.algo.ts:210 // const result = op.sqrt(a) frame_dig -1 sqrt - // tests/artifacts/miscellaneous-ops/contract.algo.ts:203 + // 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:206-207 + // 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:208 + // 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:209 + // 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 index 3825523..ad99366 100644 --- a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json +++ b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json @@ -115,6 +115,11 @@ "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" @@ -172,7 +177,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMzgKICAgIHB1c2hieXRlc3MgMHg0NTg0N2VlYSAweGY1N2FjZWI1IDB4N2Q2MzE3MzAgMHhhMWIyNDQ0MSAweGNkN2JlMWFjIDB4N2NmZGE2NGIgMHg1NGE5MTBkOSAweGM0NjU2OGRlIDB4N2E0NmE2YWUgMHgwNDM3MjIwOSAweDdlNWY2ZDcyIDB4MjRlYmNmODQgMHg5YzBiMzM5NyAweDBhZDQwZGE0IDB4OTUxNzg4NzAgMHhkZWVkYzk5YiAweGFiMjE1MGJiIDB4MDJhNTQwMTcgMHgzZGI2NmI0MSAweGM3ZWE4YzJhIDB4MWRjZWE1MGMgMHgxNjE2NmY5YSAweDJmNDcyMDY1IDB4ZDVhNzM5YzMgMHg2MWYzYjNlMSAweDU2Y2YzNjhiIDB4OTE5ZmZiZDIgMHg4ZTMwZjRlNyAweDg5ZjgxZDkyIDB4ZDUyNjAzMjcgMHgxMTRjOGM2ZCAweDM5ZTllNjJhIDB4ZDZhNGMwNWUgMHgxZWY4MTUxYSAvLyBtZXRob2QgInZlcmlmeV9hZGR3KHVpbnQ2NCx1aW50NjQpKHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZChieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYmFzZTY0X2RlY29kZV91cmwoYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J5dGVzX2JpdGxlbihieXRlW10sdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3VpbnQ2NF9iaXRsZW4odWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2JzcXJ0KGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9idG9pKGJ5dGVbXSl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9iemVybyh1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfY29uY2F0KGJ5dGVbXSxieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9kaXZtb2R3KHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCkodWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0KSIsIG1ldGhvZCAidmVyaWZ5X2RpdncodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZXJyKCl2b2lkIiwgbWV0aG9kICJ2ZXJpZnlfZXhwKHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZXhwdyh1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0KSIsIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3QoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF9mcm9tXzIoYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3RfdWludDE2KGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF91aW50MzIoYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9leHRyYWN0X3VpbnQ2NChieXRlW10sdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2dldGJpdF9ieXRlcyhieXRlW10sdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2dldGJpdF91aW50NjQodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9nZXRieXRlKGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfaXRvYih1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfbXVsdyh1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0KSIsIG1ldGhvZCAidmVyaWZ5X3JlcGxhY2UoYnl0ZVtdLHVpbnQ2NCxieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2VsZWN0X2J5dGVzKGJ5dGVbXSxieXRlW10sdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3NlbGVjdF91aW50NjQodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfc2V0Yml0X2J5dGVzKGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3NldGJpdF91aW50NjQodWludDY0LHVpbnQ2NCx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfc2V0Ynl0ZShieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9zaGwodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zaHIodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zcXJ0KHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zdWJzdHJpbmcoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FkZHdfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZF9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybF9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlc19iaXRsZW5fcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludDY0X2JpdGxlbl9yb3V0ZUA2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ic3FydF9yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9idG9pX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J6ZXJvX3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2NvbmNhdF9yb3V0ZUAxMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZGl2bW9kd19yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZGl2d19yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXJyX3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHBfcm91dGVAMTQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4cHdfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3Rfcm91dGVAMTYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfZnJvbV8yX3JvdXRlQDE3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHRyYWN0X3VpbnQxNl9yb3V0ZUAxOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF91aW50MzJfcm91dGVAMTkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfdWludDY0X3JvdXRlQDIwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRiaXRfYnl0ZXNfcm91dGVAMjEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF91aW50NjRfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJ5dGVfcm91dGVAMjMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2l0b2Jfcm91dGVAMjQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X211bHdfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3JlcGxhY2Vfcm91dGVAMjYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF9ieXRlc19yb3V0ZUAyNyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2VsZWN0X3VpbnQ2NF9yb3V0ZUAyOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Yml0X2J5dGVzX3JvdXRlQDI5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZXRiaXRfdWludDY0X3JvdXRlQDMwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZXRieXRlX3JvdXRlQDMxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaGxfcm91dGVAMzIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3Nocl9yb3V0ZUAzMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3FydF9yb3V0ZUAzNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3Vic3RyaW5nX3JvdXRlQDM1CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWRkd19yb3V0ZUAyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hZGR3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmFzZTY0X2RlY29kZV91cmxfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmFzZTY0X2RlY29kZV91cmwKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfYml0bGVuX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2JpdGxlbgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9iaXRsZW5fcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50NjRfYml0bGVuCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnNxcnRfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnNxcnQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnRvaV9yb3V0ZUA4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9idG9pCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnplcm9fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iemVybwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9jb25jYXRfcm91dGVAMTA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9jb25jYXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZGl2bW9kd19yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9kaXZtb2R3CiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIHVuY292ZXIgMwogICAgaXRvYgogICAgdW5jb3ZlciAzCiAgICBpdG9iCiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAzCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZ3X3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2RpdncKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lcnJfcm91dGVAMTM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgdmVyaWZ5X2VycgogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4cF9yb3V0ZUAxNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjgwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHAKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHB3X3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4cHcKICAgIHN3YXAKICAgIGl0b2IKICAgIHN3YXAKICAgIGl0b2IKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3Rfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3QKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9mcm9tXzJfcm91dGVAMTc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfZnJvbV8yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfdWludDE2X3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfdWludDE2CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF91aW50MzJfcm91dGVAMTk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXh0cmFjdF91aW50MzIKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHRyYWN0X3VpbnQ2NF9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHRyYWN0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF9ieXRlc19yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9nZXRiaXRfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRiaXRfdWludDY0X3JvdXRlQDIyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0Yml0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJ5dGVfcm91dGVAMjM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0Ynl0ZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2l0b2Jfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9pdG9iCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X211bHdfcm91dGVAMjU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9tdWx3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9yZXBsYWNlX3JvdXRlQDI2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9yZXBsYWNlCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF9ieXRlc19yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2VsZWN0X2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF91aW50NjRfcm91dGVAMjg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zZWxlY3RfdWludDY0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Yml0X2J5dGVzX3JvdXRlQDI5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NldGJpdF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZXRiaXRfdWludDY0X3JvdXRlQDMwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2V0Yml0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NldGJ5dGVfcm91dGVAMzE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2V0Ynl0ZQogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaGxfcm91dGVAMzI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaHJfcm91dGVAMzM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaHIKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zcXJ0X3JvdXRlQDM0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc3FydAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N1YnN0cmluZ19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdWJzdHJpbmcKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMzg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA0MgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA0MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9hZGR3KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQsIHVpbnQ2NDoKdmVyaWZ5X2FkZHc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0LTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FkZHcoYTogdWludDY0LCBiOiB1aW50NjQpOiByZWFkb25seSBbdWludDY0LCB1aW50NjRdIHsKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NgogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYWRkdyhhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFkZHcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwLTExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkKGE6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMgogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYmFzZTY0RGVjb2RlKEJhc2U2NC5TdGRFbmNvZGluZywgYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYmFzZTY0X2RlY29kZSBTdGRFbmNvZGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYtMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsKGE6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYmFzZTY0RGVjb2RlKEJhc2U2NC5VUkxFbmNvZGluZywgYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYmFzZTY0X2RlY29kZSBVUkxFbmNvZGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVzX2JpdGxlbihhOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlc19iaXRsZW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMi0yMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfYml0bGVuKGE6IGJ5dGVzLCBwYWRfYV9zaXplOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyNAogICAgLy8gY29uc3QgcGFkZGVkQSA9IG9wLmJ6ZXJvKHBhZF9hX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5iaXRMZW5ndGgocGFkZGVkQSkKICAgIGJpdGxlbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3VpbnQ2NF9iaXRsZW4oYTogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV91aW50NjRfYml0bGVuOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjktMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnQ2NF9iaXRsZW4oYTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJpdExlbmd0aChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiaXRsZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9ic3FydChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ic3FydDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM1LTM2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ic3FydChhOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJzcXJ0KGFfYmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgYnNxcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5CiAgICAvLyByZXR1cm4gQnl0ZXMocmVzdWx0KQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfYnRvaShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnRvaToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyLTQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9idG9pKGE6IGJ5dGVzKTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJ0b2koYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J6ZXJvKGE6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9iemVybzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4LTQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iemVybyhhOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjUwCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5iemVybyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBiemVybwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIHJldHVybiBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9jb25jYXQoYTogYnl0ZXMsIGI6IGJ5dGVzLCBwYWRfYV9zaXplOiB1aW50NjQsIHBhZF9iX3NpemU6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9jb25jYXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1NC01NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfY29uY2F0KGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byA0IDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU2CiAgICAvLyBjb25zdCBwYWRkZWRBID0gb3AuYnplcm8ocGFkX2Ffc2l6ZSkuY29uY2F0KGEpCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTQKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTcKICAgIC8vIGNvbnN0IHBhZGRlZEIgPSBvcC5iemVybyhwYWRfYl9zaXplKS5jb25jYXQoYikKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1OAogICAgLy8gY29uc3QgcmVzdWx0ID0gcGFkZGVkQS5jb25jYXQocGFkZGVkQikKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkKICAgIC8vIGNvbnN0IHJlc3VsdEhhc2ggPSBvcC5zaGEyNTYocmVzdWx0KQogICAgc2hhMjU2CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2MAogICAgLy8gcmV0dXJuIHJlc3VsdEhhc2gKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2Rpdm1vZHcoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCwgZDogdWludDY0KSAtPiB1aW50NjQsIHVpbnQ2NCwgdWludDY0LCB1aW50NjQ6CnZlcmlmeV9kaXZtb2R3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMtNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Rpdm1vZHcoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCwgZDogdWludDY0KTogcmVhZG9ubHkgW3VpbnQ2NCwgdWludDY0LCB1aW50NjQsIHVpbnQ2NF0gewogICAgcHJvdG8gNCA0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZGl2bW9kdyhhLCBiLCBjLCBkKQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBkaXZtb2R3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2NgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZGl2dyhhOiB1aW50NjQsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9kaXZ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjktNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2RpdncoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5kaXZ3KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBkaXZ3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3MgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXJyKCkgLT4gdm9pZDoKdmVyaWZ5X2VycjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1LTc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9lcnIoKTogdm9pZCB7CiAgICBwcm90byAwIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3CiAgICAvLyBlcnIoKQogICAgZXJyCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXhwKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4MC04MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXhwKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmV4cChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4cAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4cHcoYTogdWludDY0LCBiOiB1aW50NjQpIC0+IHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfZXhwdzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2LTg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9leHB3KGE6IHVpbnQ2NCwgYjogdWludDY0KTogcmVhZG9ubHkgW3VpbnQ2NCwgdWludDY0XSB7CiAgICBwcm90byAyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjg4CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHB3KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXhwdwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4dHJhY3QoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2V4dHJhY3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5Mi05MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXh0cmFjdChhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjk0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHRyYWN0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0MwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4dHJhY3RfZnJvbV8yKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2V4dHJhY3RfZnJvbV8yOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTgtOTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3RfZnJvbV8yKGE6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMDAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmV4dHJhY3QoYSwgMiwgMCkKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXh0cmFjdF91aW50MTYoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZXh0cmFjdF91aW50MTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMDQtMTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9leHRyYWN0X3VpbnQxNihhOiBieXRlcywgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA2CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHRyYWN0VWludDE2KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdF91aW50MTYKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXh0cmFjdF91aW50MzIoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZXh0cmFjdF91aW50MzI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTAtMTExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9leHRyYWN0X3VpbnQzMihhOiBieXRlcywgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHRyYWN0VWludDMyKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdF91aW50MzIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZXh0cmFjdF91aW50NjQoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZXh0cmFjdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTYtMTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9leHRyYWN0X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE4CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHRyYWN0VWludDY0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdF91aW50NjQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExOQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZ2V0Yml0X2J5dGVzKGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldGJpdF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMi0xMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2dldGJpdF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5nZXRCaXQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBnZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfZ2V0Yml0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0Yml0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOC0xMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2dldGJpdF91aW50NjQoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmdldEJpdChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGdldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9nZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X2dldGJ5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzQtMTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9nZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmdldEJ5dGUoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBnZXRieXRlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2l0b2IoYTogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X2l0b2I6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDAtMTQxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9pdG9iKGE6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5pdG9iKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfbXVsdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQ6CnZlcmlmeV9tdWx3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ2LTE0NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfbXVsdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHJlYWRvbmx5IFt1aW50NjQsIHVpbnQ2NF0gewogICAgcHJvdG8gMiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLm11bHcoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBtdWx3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3JlcGxhY2UoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfcmVwbGFjZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1Mi0xNTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3JlcGxhY2UoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AucmVwbGFjZShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgcmVwbGFjZTMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc2VsZWN0X2J5dGVzKGE6IGJ5dGVzLCBiOiBieXRlcywgYzogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NlbGVjdF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1OC0xNTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NlbGVjdF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYwCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZWxlY3QoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNlbGVjdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYxCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZWxlY3RfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NlbGVjdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjQtMTY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZWxlY3RfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNlbGVjdChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2VsZWN0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjcKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NldGJpdF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IGJ5dGVzOgp2ZXJpZnlfc2V0Yml0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcwLTE3MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2V0Yml0X2J5dGVzKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZXRCaXQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTczCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpIC0+IHVpbnQ2NDoKdmVyaWZ5X3NldGJpdF91aW50NjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNzYtMTc3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNzgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNldEJpdChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2V0Yml0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNzkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NldGJ5dGUoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NldGJ5dGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODItMTgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZXRCeXRlKGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZXRieXRlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODUKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NobChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc2hsOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg4LTE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2hsKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkwCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zaGwoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaGwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc2hyKGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9zaHI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTQtMTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zaHIoYTogdWludDY0LCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnNocihhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNocgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zcXJ0KGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc3FydDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMC0yMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NxcnQoYTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zcXJ0KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHNxcnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc3Vic3RyaW5nKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zdWJzdHJpbmc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDYtMjA3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdWJzdHJpbmcoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnN1YnN0cmluZyhhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc3Vic3RyaW5nMwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIK=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0-IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMzkKICAgIHB1c2hieXRlc3MgMHg0NTg0N2VlYSAweGY1N2FjZWI1IDB4N2Q2MzE3MzAgMHhhMWIyNDQ0MSAweGNkN2JlMWFjIDB4N2NmZGE2NGIgMHg1NGE5MTBkOSAweGM0NjU2OGRlIDB4N2E0NmE2YWUgMHgwNDM3MjIwOSAweDdlNWY2ZDcyIDB4MjRlYmNmODQgMHg5YzBiMzM5NyAweDBhZDQwZGE0IDB4OTUxNzg4NzAgMHhkZWVkYzk5YiAweGFiMjE1MGJiIDB4MDJhNTQwMTcgMHgzZGI2NmI0MSAweGM3ZWE4YzJhIDB4MWRjZWE1MGMgMHgxNjE2NmY5YSAweDJmNDcyMDY1IDB4YzU4ZDMwZTAgMHhkNWE3MzljMyAweDYxZjNiM2UxIDB4NTZjZjM2OGIgMHg5MTlmZmJkMiAweDhlMzBmNGU3IDB4ODlmODFkOTIgMHhkNTI2MDMyNyAweDExNGM4YzZkIDB4MzllOWU2MmEgMHhkNmE0YzA1ZSAweDFlZjgxNTFhIC8vIG1ldGhvZCAidmVyaWZ5X2FkZHcodWludDY0LHVpbnQ2NCkodWludDY0LHVpbnQ2NCkiLCBtZXRob2QgInZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkKGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybChieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZXNfYml0bGVuKGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfdWludDY0X2JpdGxlbih1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYnNxcnQoYnl0ZVtdKWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2J0b2koYnl0ZVtdKXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2J6ZXJvKHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9jb25jYXQoYnl0ZVtdLGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X2Rpdm1vZHcodWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0KSh1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfZGl2dyh1aW50NjQsdWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9lcnIoKXZvaWQiLCBtZXRob2QgInZlcmlmeV9leHAodWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9leHB3KHVpbnQ2NCx1aW50NjQpKHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdChieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9leHRyYWN0X2Zyb21fMihieXRlW10pYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfZXh0cmFjdF91aW50MTYoYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9leHRyYWN0X3VpbnQzMihieXRlW10sdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2V4dHJhY3RfdWludDY0KGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZ2V0Yml0X2J5dGVzKGJ5dGVbXSx1aW50NjQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfZ2V0Yml0X3VpbnQ2NCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2dldGJ5dGUoYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9pdG9iKHVpbnQ2NClieXRlW10iLCBtZXRob2QgInZlcmlmeV9ieXRlc19sZW4oYnl0ZVtdLHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9tdWx3KHVpbnQ2NCx1aW50NjQpKHVpbnQ2NCx1aW50NjQpIiwgbWV0aG9kICJ2ZXJpZnlfcmVwbGFjZShieXRlW10sdWludDY0LGJ5dGVbXSlieXRlW10iLCBtZXRob2QgInZlcmlmeV9zZWxlY3RfYnl0ZXMoYnl0ZVtdLGJ5dGVbXSx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2VsZWN0X3VpbnQ2NCh1aW50NjQsdWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zZXRiaXRfYnl0ZXMoYnl0ZVtdLHVpbnQ2NCx1aW50NjQpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfc2V0Yml0X3VpbnQ2NCh1aW50NjQsdWludDY0LHVpbnQ2NCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9zZXRieXRlKGJ5dGVbXSx1aW50NjQsdWludDY0KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3NobCh1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3Nocih1aW50NjQsdWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3NxcnQodWludDY0KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X3N1YnN0cmluZyhieXRlW10sdWludDY0LHVpbnQ2NClieXRlW10iCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWRkd19yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2JpdGxlbl9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50NjRfYml0bGVuX3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JzcXJ0X3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J0b2lfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnplcm9fcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfY29uY2F0X3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZtb2R3X3JvdXRlQDExIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZ3X3JvdXRlQDEyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9lcnJfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4cF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXhwd19yb3V0ZUAxNSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9mcm9tXzJfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfdWludDE2X3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHRyYWN0X3VpbnQzMl9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF91aW50NjRfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF9ieXRlc19yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0Yml0X3VpbnQ2NF9yb3V0ZUAyMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZ2V0Ynl0ZV9yb3V0ZUAyMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfaXRvYl9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbGVuX3JvdXRlQDI1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9tdWx3X3JvdXRlQDI2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9yZXBsYWNlX3JvdXRlQDI3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZWxlY3RfYnl0ZXNfcm91dGVAMjggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF91aW50NjRfcm91dGVAMjkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NldGJpdF9ieXRlc19yb3V0ZUAzMCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Yml0X3VpbnQ2NF9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Ynl0ZV9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hsX3JvdXRlQDMzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaHJfcm91dGVAMzQgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NxcnRfcm91dGVAMzUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N1YnN0cmluZ19yb3V0ZUAzNgogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FkZHdfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hZGR3CiAgICBzd2FwCiAgICBpdG9iCiAgICBzd2FwCiAgICBpdG9iCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybF9yb3V0ZUA0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfdXJsCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVzX2JpdGxlbl9yb3V0ZUA1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVzX2JpdGxlbgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnQ2NF9iaXRsZW5fcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnQ2NF9iaXRsZW4KICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ic3FydF9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JzcXJ0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J0b2lfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9idG9pCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnplcm9fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J6ZXJvCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2NvbmNhdF9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDQKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfY29uY2F0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Rpdm1vZHdfcm91dGVAMTE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9kaXZtb2R3CiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIHVuY292ZXIgMwogICAgaXRvYgogICAgdW5jb3ZlciAzCiAgICBpdG9iCiAgICB1bmNvdmVyIDMKICAgIGl0b2IKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAzCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9kaXZ3X3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZGl2dwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2Vycl9yb3V0ZUAxMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHZlcmlmeV9lcnIKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHBfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHAKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHB3X3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXhwdwogICAgc3dhcAogICAgaXRvYgogICAgc3dhcAogICAgaXRvYgogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF9yb3V0ZUAxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjkyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHRyYWN0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfZnJvbV8yX3JvdXRlQDE3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfZnJvbV8yCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2V4dHJhY3RfdWludDE2X3JvdXRlQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZXh0cmFjdF91aW50MTYKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9leHRyYWN0X3VpbnQzMl9yb3V0ZUAxOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2V4dHJhY3RfdWludDMyCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfZXh0cmFjdF91aW50NjRfcm91dGVAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9leHRyYWN0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF9ieXRlc19yb3V0ZUAyMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldGJpdF9ieXRlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2dldGJpdF91aW50NjRfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2dldGJpdF91aW50NjQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9nZXRieXRlX3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfZ2V0Ynl0ZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2l0b2Jfcm91dGVAMjQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2l0b2IKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZXNfbGVuX3JvdXRlQDI1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZXNfbGVuCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfbXVsd19yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfbXVsdwogICAgc3dhcAogICAgaXRvYgogICAgc3dhcAogICAgaXRvYgogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcmVwbGFjZV9yb3V0ZUAyNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9yZXBsYWNlCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NlbGVjdF9ieXRlc19yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zZWxlY3RfYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2VsZWN0X3VpbnQ2NF9yb3V0ZUAyOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfc2VsZWN0X3VpbnQ2NAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NldGJpdF9ieXRlc19yb3V0ZUAzMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NldGJpdF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zZXRiaXRfdWludDY0X3JvdXRlQDMxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zZXRiaXRfdWludDY0CiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2V0Ynl0ZV9yb3V0ZUAzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MwogICAgLy8gZXhwb3J0IGNsYXNzIE1pc2NlbGxhbmVvdXNPcHNDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NldGJ5dGUKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc2hsX3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zaGwKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zaHJfcm91dGVAMzQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NocgogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3NxcnRfcm91dGVAMzU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3NxcnQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdWJzdHJpbmdfcm91dGVAMzY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMKICAgIC8vIGV4cG9ydCBjbGFzcyBNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdWJzdHJpbmcKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMzk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA0MwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozCiAgICAvLyBleHBvcnQgY2xhc3MgTWlzY2VsbGFuZW91c09wc0NvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICBpbnRjXzEgLy8gMAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfYWRkdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQ6CnZlcmlmeV9hZGR3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NC01CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hZGR3KGE6IHVpbnQ2NCwgYjogdWludDY0KTogcmVhZG9ubHkgW3VpbnQ2NCwgdWludDY0XSB7CiAgICBwcm90byAyIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjYKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmFkZHcoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBhZGR3CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iYXNlNjRfZGVjb2RlX3N0YW5kYXJkKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2Jhc2U2NF9kZWNvZGVfc3RhbmRhcmQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMC0xMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmFzZTY0X2RlY29kZV9zdGFuZGFyZChhOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJhc2U2NERlY29kZShCYXNlNjQuU3RkRW5jb2RpbmcsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhc2U2NF9kZWNvZGUgU3RkRW5jb2RpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybChhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2LTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iYXNlNjRfZGVjb2RlX3VybChhOiBieXRlcyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmJhc2U2NERlY29kZShCYXNlNjQuVVJMRW5jb2RpbmcsIGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhc2U2NF9kZWNvZGUgVVJMRW5jb2RpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19iaXRsZW4oYTogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZXNfYml0bGVuOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjItMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVzX2JpdGxlbihhOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfYV9zaXplKS5jb25jYXQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyNQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYml0TGVuZ3RoKHBhZGRlZEEpCiAgICBiaXRsZW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV91aW50NjRfYml0bGVuKGE6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfdWludDY0X2JpdGxlbjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50NjRfYml0bGVuKGE6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5iaXRMZW5ndGgoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYml0bGVuCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozMgogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfYnNxcnQoYTogYnl0ZXMpIC0-IGJ5dGVzOgp2ZXJpZnlfYnNxcnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozNS0zNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnNxcnQoYTogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjM4CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5ic3FydChhX2JpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJzcXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czozOQogICAgLy8gcmV0dXJuIEJ5dGVzKHJlc3VsdCkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2J0b2koYTogYnl0ZXMpIC0-IHVpbnQ2NDoKdmVyaWZ5X2J0b2k6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0Mi00MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnRvaShhOiBieXRlcyk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5idG9pKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9iemVybyhhOiB1aW50NjQpIC0-IGJ5dGVzOgp2ZXJpZnlfYnplcm86CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo0OC00OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnplcm8oYTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1MAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuYnplcm8oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyByZXR1cm4gb3Auc2hhMjU2KHJlc3VsdCkKICAgIHNoYTI1NgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfY29uY2F0KGE6IGJ5dGVzLCBiOiBieXRlcywgcGFkX2Ffc2l6ZTogdWludDY0LCBwYWRfYl9zaXplOiB1aW50NjQpIC0-IGJ5dGVzOgp2ZXJpZnlfY29uY2F0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTQtNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2NvbmNhdChhOiBieXRlcywgYjogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCwgcGFkX2Jfc2l6ZTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gNCAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo1NgogICAgLy8gY29uc3QgcGFkZGVkQSA9IG9wLmJ6ZXJvKHBhZF9hX3NpemUpLmNvbmNhdChhKQogICAgZnJhbWVfZGlnIC0yCiAgICBiemVybwogICAgZnJhbWVfZGlnIC00CiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU3CiAgICAvLyBjb25zdCBwYWRkZWRCID0gb3AuYnplcm8ocGFkX2Jfc2l6ZSkuY29uY2F0KGIpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTMKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTgKICAgIC8vIGNvbnN0IHJlc3VsdCA9IHBhZGRlZEEuY29uY2F0KHBhZGRlZEIpCiAgICBjb25jYXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjU5CiAgICAvLyBjb25zdCByZXN1bHRIYXNoID0gb3Auc2hhMjU2KHJlc3VsdCkKICAgIHNoYTI1NgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAKICAgIC8vIHJldHVybiByZXN1bHRIYXNoCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9kaXZtb2R3KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQsIGQ6IHVpbnQ2NCkgLT4gdWludDY0LCB1aW50NjQsIHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfZGl2bW9kdzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjYzLTY0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9kaXZtb2R3KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQsIGQ6IHVpbnQ2NCk6IHJlYWRvbmx5IFt1aW50NjQsIHVpbnQ2NCwgdWludDY0LCB1aW50NjRdIHsKICAgIHByb3RvIDQgNAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmRpdm1vZHcoYSwgYiwgYywgZCkKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZGl2bW9kdwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2RpdncoYTogdWludDY0LCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZGl2dzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjY5LTcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9kaXZ3KGE6IHVpbnQ2NCwgYjogdWludDY0LCBjOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3MQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZGl2dyhhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZGl2dwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2VycigpIC0-IHZvaWQ6CnZlcmlmeV9lcnI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3NS03NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXJyKCk6IHZvaWQgewogICAgcHJvdG8gMCAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gZXJyKCkKICAgIGVycgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2V4cChhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZXhwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODAtODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4cChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5leHAoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjgzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHB3KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQsIHVpbnQ2NDoKdmVyaWZ5X2V4cHc6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4Ni04NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXhwdyhhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHJlYWRvbmx5IFt1aW50NjQsIHVpbnQ2NF0gewogICAgcHJvdG8gMiAyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo4OAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXhwdyhhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4cHcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0KGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9leHRyYWN0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTItOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3QoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo5NAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXh0cmFjdChhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdDMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjk1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X2Zyb21fMihhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9leHRyYWN0X2Zyb21fMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjk5LTEwMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZXh0cmFjdF9mcm9tXzIoYTogYnl0ZXMpOiBieXRlcyB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZXh0cmFjdChhLCAyLCAwKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAyCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQxNihhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNS0xMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3RfdWludDE2KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMDcKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmV4dHJhY3RVaW50MTYoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0X3VpbnQxNgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA4CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQzMihhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQzMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExMS0xMTIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3RfdWludDMyKGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTMKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmV4dHJhY3RVaW50MzIoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0X3VpbnQzMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9leHRyYWN0X3VpbnQ2NChhOiBieXRlcywgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9leHRyYWN0X3VpbnQ2NDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNy0xMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2V4dHJhY3RfdWludDY0KGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMTkKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmV4dHJhY3RVaW50NjQoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0X3VpbnQ2NAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIwCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9nZXRiaXRfYnl0ZXMoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0Yml0X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzLTEyNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZ2V0Yml0X2J5dGVzKGE6IGJ5dGVzLCBiOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmdldEJpdChhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGdldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9nZXRiaXRfdWludDY0KGE6IHVpbnQ2NCwgYjogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9nZXRiaXRfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI5LTEzMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfZ2V0Yml0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMQogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZ2V0Qml0KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgZ2V0Yml0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxMzIKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X2dldGJ5dGUoYTogYnl0ZXMsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfZ2V0Ynl0ZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNS0xMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2dldGJ5dGUoYTogYnl0ZXMsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gY29uc3QgcmVzdWx0ID0gb3AuZ2V0Qnl0ZShhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGdldGJ5dGUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzOAogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfaXRvYihhOiB1aW50NjQpIC0-IGJ5dGVzOgp2ZXJpZnlfaXRvYjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MS0xNDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2l0b2IoYTogdWludDY0KTogYnl0ZXMgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDMKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLml0b2IoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ0CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9ieXRlc19sZW4oYTogYnl0ZXMsIHBhZF9hX3NpemU6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZXNfbGVuOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ3LTE0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZXNfbGVuKGE6IGJ5dGVzLCBwYWRfYV9zaXplOiB1aW50NjQpOiB1aW50NjQgewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIGNvbnN0IHBhZGRlZEEgPSBvcC5iemVybyhwYWRfYV9zaXplKS5jb25jYXQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNTAKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLmxlbihwYWRkZWRBKQogICAgbGVuCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNTEKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X211bHcoYTogdWludDY0LCBiOiB1aW50NjQpIC0-IHVpbnQ2NCwgdWludDY0Ogp2ZXJpZnlfbXVsdzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NC0xNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X211bHcoYTogdWludDY0LCBiOiB1aW50NjQpOiByZWFkb25seSBbdWludDY0LCB1aW50NjRdIHsKICAgIHByb3RvIDIgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU2CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5tdWx3KGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgbXVsdwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTU3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9yZXBsYWNlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3JlcGxhY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjAtMTYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9yZXBsYWNlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IGJ5dGVzKTogYnl0ZXMgewogICAgcHJvdG8gMyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjIKICAgIC8vIGNvbnN0IHJlc3VsdCA9IG9wLnJlcGxhY2UoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHJlcGxhY2UzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjMKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NlbGVjdF9ieXRlcyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zZWxlY3RfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxNjYtMTY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zZWxlY3RfYnl0ZXMoYTogYnl0ZXMsIGI6IGJ5dGVzLCBjOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Auc2VsZWN0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZWxlY3QKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc2VsZWN0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9zZWxlY3RfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcyLTE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2VsZWN0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCwgYzogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZWxlY3QoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNlbGVjdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc1CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRiaXRfYnl0ZXMoYTogYnl0ZXMsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiBieXRlczoKdmVyaWZ5X3NldGJpdF9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OC0xNzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NldGJpdF9ieXRlcyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Auc2V0Qml0KGEsIGIsIGMpCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzZXRiaXQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4MQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc2V0Yml0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCwgYzogdWludDY0KSAtPiB1aW50NjQ6CnZlcmlmeV9zZXRiaXRfdWludDY0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg0LTE4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2V0Yml0X3VpbnQ2NChhOiB1aW50NjQsIGI6IHVpbnQ2NCwgYzogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg2CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zZXRCaXQoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHNldGJpdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg3CiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zZXRieXRlKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCkgLT4gYnl0ZXM6CnZlcmlmeV9zZXRieXRlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkwLTE5MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2V0Ynl0ZShhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpOiBieXRlcyB7CiAgICBwcm90byAzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MgogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Auc2V0Qnl0ZShhLCBiLCBjKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2V0Ynl0ZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTkzCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LnZlcmlmeV9zaGwoYTogdWludDY0LCBiOiB1aW50NjQpIC0-IHVpbnQ2NDoKdmVyaWZ5X3NobDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5Ni0xOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3NobChhOiB1aW50NjQsIGI6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5OAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Auc2hsKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgc2hsCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoxOTkKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3NocihhOiB1aW50NjQsIGI6IHVpbnQ2NCkgLT4gdWludDY0Ogp2ZXJpZnlfc2hyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyLTIwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc2hyKGE6IHVpbnQ2NCwgYjogdWludDY0KTogdWludDY0IHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA0CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zaHIoYSwgYikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBzaHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6Ok1pc2NlbGxhbmVvdXNPcHNDb250cmFjdC52ZXJpZnlfc3FydChhOiB1aW50NjQpIC0-IHVpbnQ2NDoKdmVyaWZ5X3NxcnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMDgtMjA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zcXJ0KGE6IHVpbnQ2NCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxMAogICAgLy8gY29uc3QgcmVzdWx0ID0gb3Auc3FydChhKQogICAgZnJhbWVfZGlnIC0xCiAgICBzcXJ0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czoyMTEKICAgIC8vIHJldHVybiByZXN1bHQKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjpNaXNjZWxsYW5lb3VzT3BzQ29udHJhY3QudmVyaWZ5X3N1YnN0cmluZyhhOiBieXRlcywgYjogdWludDY0LCBjOiB1aW50NjQpIC0-IGJ5dGVzOgp2ZXJpZnlfc3Vic3RyaW5nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE0LTIxNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3Vic3RyaW5nKGE6IGJ5dGVzLCBiOiB1aW50NjQsIGM6IHVpbnQ2NCk6IGJ5dGVzIHsKICAgIHByb3RvIDMgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL21pc2NlbGxhbmVvdXMtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE2CiAgICAvLyBjb25zdCByZXN1bHQgPSBvcC5zdWJzdHJpbmcoYSwgYiwgYykKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHN1YnN0cmluZzMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9taXNjZWxsYW5lb3VzLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNwogICAgLy8gcmV0dXJuIHJlc3VsdAogICAgcmV0c3ViCg==", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvbWlzY2VsbGFuZW91cy1vcHMvY29udHJhY3QuYWxnby50czo6TWlzY2VsbGFuZW91c09wc0NvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" }, "state": { @@ -572,6 +577,23 @@ "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": [ diff --git a/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc56.json b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc56.json new file mode 100644 index 0000000..2c01953 --- /dev/null +++ b/tests/artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc56.json @@ -0,0 +1,1024 @@ +{ + "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/pure-op-codes.spec.ts b/tests/pure-op-codes.spec.ts index 9f795c4..7ab8575 100644 --- a/tests/pure-op-codes.spec.ts +++ b/tests/pure-op-codes.spec.ts @@ -672,6 +672,24 @@ describe('Pure op codes', async () => { }) }) + 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], + [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) + const result = op.len(paddedA) + expect(result).toEqual(avmResult) + }) + }) + describe('mulw', async () => { test.each([ [0, 0], From 6685c92e45712a6c0162e9da5cae8e6e8bb91dcf Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 19 Dec 2024 19:48:06 +0800 Subject: [PATCH 72/85] feat: implement stubs for appOptedIn, ensureBudget, TemplateVar refactor: function call replacement (...Impl) in visitor to be more resilient by catering for the following cases - module name prefix (e.g. `arc4.interpretAsArc4`) - import name alias (e.g. `import { interpretAsArc4 as interpret } from '@algorandfoundation/algorand-typescript/arc4'`) - function name conflict (e.g. ``` import { interpretAsArc4 as interpret } .... const interpretAsArc4 = () => {...} ```) feat: add arc4 value generator feat: add zk-whitelist example contract and tests --- examples/rollup.config.ts | 1 + examples/zk-whitelist/contract.algo.ts | 94 ++++++++++++++++++++ examples/zk-whitelist/contract.spec.ts | 79 +++++++++++++++++ src/constants.ts | 5 ++ src/impl/acct-params.ts | 16 +++- src/impl/ensure-budget.ts | 5 ++ src/impl/index.ts | 2 +- src/impl/template-var.ts | 11 +++ src/runtime-helpers.ts | 3 + src/test-execution-context.ts | 15 +++- src/test-transformer/node-factory.ts | 5 +- src/test-transformer/visitors.ts | 59 ++++++++----- src/value-generators/arc4.ts | 114 +++++++++++++++++++++++++ src/value-generators/index.ts | 3 + 14 files changed, 386 insertions(+), 26 deletions(-) create mode 100644 examples/zk-whitelist/contract.algo.ts create mode 100644 examples/zk-whitelist/contract.spec.ts create mode 100644 src/impl/ensure-budget.ts create mode 100644 src/impl/template-var.ts create mode 100644 src/value-generators/arc4.ts diff --git a/examples/rollup.config.ts b/examples/rollup.config.ts index bc04ab8..79ef1aa 100644 --- a/examples/rollup.config.ts +++ b/examples/rollup.config.ts @@ -12,6 +12,7 @@ const config: RollupOptions = { 'examples/auction/contract.algo.ts', 'examples/voting/contract.algo.ts', 'examples/simple-voting/contract.algo.ts', + 'examples/zk-whitelist/contract.algo.ts', ], output: [ { diff --git a/examples/zk-whitelist/contract.algo.ts b/examples/zk-whitelist/contract.algo.ts new file mode 100644 index 0000000..d1a9224 --- /dev/null +++ b/examples/zk-whitelist/contract.algo.ts @@ -0,0 +1,94 @@ +import { + abimethod, + Account, + arc4, + assert, + BigUint, + Bytes, + ensureBudget, + Global, + itxn, + LocalState, + op, + OpUpFeeSource, + TemplateVar, + Txn, + uint64, +} from '@algorandfoundation/algorand-typescript' + +const curveMod = 21888242871839275222246405745257275088548364400416034343698204186575808495617n +const verifierBudget = 145000 + +export default class ZkWhitelistContract extends arc4.Contract { + appName: arc4.Str | undefined + whiteList = LocalState() + + @abimethod({ onCreate: 'require' }) + create(name: arc4.Str) { + // Create the application + this.appName = name + } + + @abimethod({ allowActions: ['UpdateApplication', 'DeleteApplication'] }) + update() { + // Update the application if it is mutable (manager only) + assert(Global.creatorAddress === Txn.sender) + } + + @abimethod({ allowActions: ['OptIn', 'CloseOut'] }) + optInOrOut() { + // Opt in or out of the application + return + } + + @abimethod() + addAddressToWhitelist(address: arc4.Address, proof: arc4.DynamicArray): arc4.Str { + /* + Add caller to the whitelist if the zk proof is valid. + On success, will return an empty string. Otherwise, will return an error + message. + */ + ensureBudget(verifierBudget, OpUpFeeSource.GroupCredit) + // The verifier expects public inputs to be in the curve field, but an + // Algorand address might represent a number larger than the field + // modulus, so to be safe we take the address modulo the field modulus + const addressMod = arc4.interpretAsArc4(op.bzero(32).bitwiseOr(Bytes(BigUint(address.bytes) % curveMod))) + // Verify the proof by calling the deposit verifier app + const verified = this.verifyProof(TemplateVar('VERIFIER_APP_ID'), proof, new arc4.DynamicArray(addressMod)) + if (!verified.native) { + return new arc4.Str('Proof verification failed') + } + // if successful, add the sender to the whitelist by setting local state + const account = Account(address.bytes) + if (Txn.sender !== account) { + return new arc4.Str('Sender address does not match authorized address') + } + this.whiteList(account).value = true + return new arc4.Str('') + } + + @abimethod() + isOnWhitelist(address: arc4.Address): arc4.Bool { + // Check if an address is on the whitelist + const account = address.native + const optedIn = op.appOptedIn(account, Global.currentApplicationId) + if (!optedIn) { + return new arc4.Bool(false) + } + const whitelisted = this.whiteList(account).value + return new arc4.Bool(whitelisted) + } + + verifyProof(appId: uint64, proof: arc4.DynamicArray, publicInputs: arc4.DynamicArray): arc4.Bool { + // Verify a proof using the verifier app. + const verified = itxn + .applicationCall({ + appId: appId, + fee: 0, + appArgs: [arc4.methodSelector('verify(byte[32][],byte[32][])bool'), proof.copy(), publicInputs.copy()], + onCompletion: arc4.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 new file mode 100644 index 0000000..468e93b --- /dev/null +++ b/examples/zk-whitelist/contract.spec.ts @@ -0,0 +1,79 @@ +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' + +describe('ZK Whitelist', () => { + const ctx = new TestExecutionContext() + + afterEach(() => { + ctx.reset() + }) + + it('should be able to add address to whitelist', () => { + // Arrange + const contract = ctx.contract.create(ZkWhitelistContract) + contract.create(ctx.any.arc4.str(10)) + + const address = new arc4.Address(ctx.defaultSender) + const proof = new arc4.DynamicArray(new arc4.Address(Bytes(new Uint8Array(Array(32).fill(0))))) + + const dummyVerifierApp = ctx.any.application({ appLogs: [ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes.fromHex('80'))] }) + ctx.setTemplateVar('VERIFIER_APP_ID', dummyVerifierApp.id) + + // Act + const result = contract.addAddressToWhitelist(address, proof) + + // Assert + expect(result.native).toEqual('') + expect(contract.whiteList(ctx.defaultSender).value).toEqual(true) + }) + + it('returns error message if proof verification fails', () => { + // Arrange + const contract = ctx.contract.create(ZkWhitelistContract) + contract.create(ctx.any.arc4.str(10)) + + const address = ctx.any.arc4.address() + const proof = new arc4.DynamicArray(new arc4.Address(Bytes(new Uint8Array(Array(32).fill(0))))) + const dummyVerifierApp = ctx.any.application({ appLogs: [ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(''))] }) + ctx.setTemplateVar('VERIFIER_APP_ID', dummyVerifierApp.id) + + // Act + const result = contract.addAddressToWhitelist(address, proof) + + // Assert + expect(result.native).toEqual('Proof verification failed') + }) + + it('returns true if address is already in whitelist', () => { + // Arrange + const contract = ctx.contract.create(ZkWhitelistContract) + contract.create(ctx.any.arc4.str(10)) + + const dummyAccount = ctx.any.account({ optedApplications: [ctx.ledger.getApplicationForContract(contract)] }) + contract.whiteList(dummyAccount).value = true + + // Act + const result = contract.isOnWhitelist(new arc4.Address(dummyAccount)) + + // Assert + expect(result.native).toBe(true) + }) + + it('returns false if address is not in whitelist', () => { + // Arrange + const contract = ctx.contract.create(ZkWhitelistContract) + contract.create(ctx.any.arc4.str(10)) + + const dummyAccount = ctx.any.account({ optedApplications: [ctx.ledger.getApplicationForContract(contract)] }) + contract.whiteList(dummyAccount).value = false + + // Act + const result = contract.isOnWhitelist(new arc4.Address(dummyAccount)) + + // Assert + expect(result.native).toBe(false) + }) +}) diff --git a/src/constants.ts b/src/constants.ts index 2637b14..b218a66 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -3,7 +3,11 @@ import { Bytes } from '@algorandfoundation/algorand-typescript' export const UINT64_SIZE = 64 export const UINT512_SIZE = 512 export const MAX_UINT8 = 2 ** 8 - 1 +export const MAX_UINT16 = 2 ** 16 - 1 +export const MAX_UINT32 = 2 ** 32 - 1 export const MAX_UINT64 = 2n ** 64n - 1n +export const MAX_UINT128 = 2n ** 128n - 1n +export const MAX_UINT256 = 2n ** 256n - 1n export const MAX_UINT512 = 2n ** 512n - 1n export const MAX_BYTES_SIZE = 4096 export const MAX_LOG_SIZE = 1024 @@ -43,6 +47,7 @@ export const ABI_RETURN_VALUE_LOG_PREFIX = Bytes.fromHex('151F7C75') export const UINT64_OVERFLOW_UNDERFLOW_MESSAGE = 'Uint64 overflow or underflow' export const BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE = 'BigUint overflow or underflow' +export const DEFAULT_TEMPLATE_VAR_PREFIX = 'TMPL_' export const APP_ID_PREFIX = 'appID' export const HASH_BYTES_LENGTH = 32 diff --git a/src/impl/acct-params.ts b/src/impl/acct-params.ts index 2864405..9042446 100644 --- a/src/impl/acct-params.ts +++ b/src/impl/acct-params.ts @@ -1,6 +1,7 @@ -import { Account, gtxn, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, Application, gtxn, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { asMaybeUint64Cls } from '../util' +import { getApp } from './app-params' export const getAccount = (acct: Account | internal.primitives.StubUint64Compat): Account => { const acctId = asMaybeUint64Cls(acct) @@ -21,6 +22,19 @@ export const minBalance = (a: Account | internal.primitives.StubUint64Compat): u return acct.minBalance } +export const appOptedIn = ( + a: Account | internal.primitives.StubUint64Compat, + b: Application | internal.primitives.StubUint64Compat, +): boolean => { + const account = getAccount(a) + const app = getApp(b) + + if (account === undefined || app === undefined) { + return false + } + return account.isOptedIn(app) +} + export const AcctParams: internal.opTypes.AcctParamsType = { acctBalance(a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { const acct = getAccount(a) diff --git a/src/impl/ensure-budget.ts b/src/impl/ensure-budget.ts new file mode 100644 index 0000000..3ebb307 --- /dev/null +++ b/src/impl/ensure-budget.ts @@ -0,0 +1,5 @@ +import { OpUpFeeSource, uint64 } 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/index.ts b/src/impl/index.ts index 2909910..42bd62b 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -1,4 +1,4 @@ -export { AcctParams, balance, minBalance } from './acct-params' +export { AcctParams, appOptedIn, balance, minBalance } from './acct-params' export { AppGlobal } from './app-global' export { AppLocal } from './app-local' export { AppParams } from './app-params' diff --git a/src/impl/template-var.ts b/src/impl/template-var.ts new file mode 100644 index 0000000..e49cfc4 --- /dev/null +++ b/src/impl/template-var.ts @@ -0,0 +1,11 @@ +import { internal } from '@algorandfoundation/algorand-typescript' +import { DEFAULT_TEMPLATE_VAR_PREFIX } from '../constants' +import { lazyContext } from '../context-helpers/internal-context' + +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!`) + } + return lazyContext.value.templateVars[prefix + variableName] as T +} diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 10e58cc..48b08d6 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -8,6 +8,8 @@ import { nameOfType } from './util' export { attachAbiMetadata } from './abi-metadata' export * from './impl/encoded-types' +export { ensureBudgetImpl } from './impl/ensure-budget' +export { TemplateVarImpl } from './impl/template-var' export function switchableValue(x: unknown): bigint | string | boolean { if (typeof x === 'boolean') return x @@ -92,6 +94,7 @@ function arc4EncodedOp(left: ARC4Encoded, right: ARC4Encoded, op: BinaryOps): De function accountBinaryOp(left: AccountCls, right: AccountCls, op: BinaryOps): DeliberateAny { switch (op) { case '===': + case '!==': return bytesBinaryOp(left.bytes, right.bytes, op) default: internal.errors.internalError(`Unsupported operator ${op}`) diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index c7723c4..efbf68e 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -1,5 +1,6 @@ -import { Account, Application, Asset, Bytes, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, Application, Asset, bytes, internal, LogicSig, uint64 } from '@algorandfoundation/algorand-typescript' import { captureMethodConfig } from './abi-metadata' +import { DEFAULT_TEMPLATE_VAR_PREFIX } from './constants' import { DecodedLogs, LogDecoding } from './decode-logs' import * as ops from './impl' import { AccountCls } from './impl/account' @@ -18,6 +19,7 @@ import { Box, BoxMap, BoxRef, GlobalState, LocalState } from './impl/state' import { ContractContext } from './subcontexts/contract-context' import { LedgerContext } from './subcontexts/ledger-context' import { TransactionContext } from './subcontexts/transaction-context' +import { DeliberateAny } from './typescript-helpers' import { getRandomBytes } from './util' import { ValueGenerator } from './value-generators' @@ -28,6 +30,7 @@ export class TestExecutionContext implements internal.ExecutionContext { #valueGenerator: ValueGenerator #defaultSender: Account #activeLogicSigArgs: bytes[] + #template_vars: Record = {} constructor(defaultSenderAddress?: bytes) { internal.ctxMgr.instance = this @@ -126,6 +129,10 @@ export class TestExecutionContext implements internal.ExecutionContext { return this.#activeLogicSigArgs } + get templateVars(): Record { + return this.#template_vars + } + executeLogicSig(logicSig: LogicSig, ...args: bytes[]): boolean | uint64 { this.#activeLogicSigArgs = args try { @@ -135,10 +142,16 @@ export class TestExecutionContext implements internal.ExecutionContext { } } + setTemplateVar(name: string, value: DeliberateAny) { + this.#template_vars[DEFAULT_TEMPLATE_VAR_PREFIX + name] = value + } + reset() { this.#contractContext = new ContractContext() this.#ledgerContext = new LedgerContext() this.#txnContext = new TransactionContext() + this.#activeLogicSigArgs = [] + this.#template_vars = {} internal.ctxMgr.reset() internal.ctxMgr.instance = this } diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 49d5607..684c734 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -94,12 +94,11 @@ export const nodeFactory = { ) }, - callARC4EncodingUtil(node: ts.CallExpression, typeInfo?: TypeInfo) { - const identifierExpression = node.expression as ts.Identifier + callStubbedFunction(functionName: string, node: ts.CallExpression, typeInfo?: TypeInfo) { const infoString = JSON.stringify(typeInfo) const updatedPropertyAccessExpression = factory.createPropertyAccessExpression( factory.createIdentifier('runtimeHelpers'), - `${identifierExpression.getText()}Impl`, + `${functionName}Impl`, ) return factory.createCallExpression( diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index 76e5edf..8275563 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -1,4 +1,5 @@ import { 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' @@ -12,10 +13,16 @@ import { const { factory } = ts +const algotsModulePaths = [ + `@algorandfoundation${path.sep}algorand-typescript`, + `${path.sep}puya-ts${path.sep}packages${path.sep}algo-ts${path.sep}`, +] + type VisitorHelper = { additionalStatements: ts.Statement[] resolveType(node: ts.Node): ptypes.PType sourceLocation(node: ts.Node): SourceLocation + tryGetSymbol(node: ts.Node): ts.Symbol | undefined } export class SourceFileVisitor { @@ -26,8 +33,8 @@ export class SourceFileVisitor { program: ts.Program, private config: TransformerConfig, ) { - const typeResolver = new TypeResolver(program.getTypeChecker(), program.getCurrentDirectory()) - + const typeChecker = program.getTypeChecker() + const typeResolver = new TypeResolver(typeChecker, program.getCurrentDirectory()) this.helper = { additionalStatements: [], resolveType(node: ts.Node): ptypes.PType { @@ -37,6 +44,10 @@ export class SourceFileVisitor { return ptypes.anyPType } }, + tryGetSymbol(node: ts.Node): ts.Symbol | undefined { + const s = typeChecker.getSymbolAtLocation(node) + return s && s.flags & ts.SymbolFlags.Alias ? typeChecker.getAliasedSymbol(s) : s + }, sourceLocation(node: ts.Node): SourceLocation { return SourceLocation.fromNode(node, program.getCurrentDirectory()) }, @@ -45,7 +56,6 @@ export class SourceFileVisitor { public result(): ts.SourceFile { const updatedSourceFile = ts.visitNode(this.sourceFile, this.visit) as ts.SourceFile - return factory.updateSourceFile(updatedSourceFile, [ nodeFactory.importHelpers(this.config.testingPackageName), ...updatedSourceFile.statements, @@ -91,20 +101,21 @@ class ExpressionVisitor { const isGeneric = isGenericType(type) const isArc4Encoded = isArc4EncodedType(type) - if (isGeneric || isArc4Encoded) { - let updatedNode = node - const info = getGenericTypeInfo(type) + const info = isGeneric || isArc4Encoded ? getGenericTypeInfo(type) : undefined + let updatedNode = node + + if (ts.isNewExpression(updatedNode)) { if (isArc4EncodedType(type)) { - if (ts.isNewExpression(updatedNode)) { - updatedNode = nodeFactory.instantiateARC4EncodedType(updatedNode, info) - } else if (ts.isCallExpression(updatedNode) && isCallingARC4EncodingUtils(updatedNode)) { - updatedNode = nodeFactory.callARC4EncodingUtil(updatedNode, info) - } + updatedNode = nodeFactory.instantiateARC4EncodedType(updatedNode, info) } - return isGeneric - ? nodeFactory.captureGenericTypeInfo(ts.visitEachChild(updatedNode, this.visit, this.context), JSON.stringify(info)) - : ts.visitEachChild(updatedNode, this.visit, this.context) } + if (ts.isCallExpression(updatedNode)) { + const stubbedFunctionName = tryGetStubbedFunctionName(updatedNode, this.helper) + updatedNode = stubbedFunctionName ? nodeFactory.callStubbedFunction(stubbedFunctionName, updatedNode, info) : updatedNode + } + return isGeneric + ? nodeFactory.captureGenericTypeInfo(ts.visitEachChild(updatedNode, this.visit, this.context), JSON.stringify(info)) + : ts.visitEachChild(updatedNode, this.visit, this.context) } return ts.visitEachChild(node, this.visit, this.context) } @@ -194,7 +205,7 @@ class FunctionOrMethodVisitor { if (ts.isNewExpression(node)) { return new ExpressionVisitor(this.context, this.helper, node).result() } - if (ts.isCallExpression(node) && isCallingARC4EncodingUtils(node)) { + if (ts.isCallExpression(node) && tryGetStubbedFunctionName(node, this.helper)) { return new ExpressionVisitor(this.context, this.helper, node).result() } @@ -331,9 +342,17 @@ const getGenericTypeInfo = (type: ptypes.PType): TypeInfo => { return result } -const isCallingARC4EncodingUtils = (node: ts.CallExpression) => { - if (node.expression.kind !== ts.SyntaxKind.Identifier) return false - const identityExpression = node.expression as ts.Identifier - const utilMethods = ['interpretAsArc4', 'decodeArc4', 'encodeArc4'] - return utilMethods.includes(identityExpression.text) +const tryGetStubbedFunctionName = (node: ts.CallExpression, helper: VisitorHelper): string | undefined => { + if (node.expression.kind !== ts.SyntaxKind.Identifier && !ts.isPropertyAccessExpression(node.expression)) return undefined + const identityExpression = ts.isPropertyAccessExpression(node.expression) + ? (node.expression as ts.PropertyAccessExpression).name + : (node.expression as ts.Identifier) + const functionSymbol = helper.tryGetSymbol(identityExpression) + if (functionSymbol) { + const sourceFileName = functionSymbol.valueDeclaration?.getSourceFile().fileName + if (sourceFileName && !algotsModulePaths.some((s) => sourceFileName.includes(s))) return undefined + } + const functionName = functionSymbol?.getName() ?? identityExpression.text + const stubbedFunctionNames = ['interpretAsArc4', 'decodeArc4', 'encodeArc4', 'TemplateVar', 'ensureBudget'] + return stubbedFunctionNames.includes(functionName) ? functionName : undefined } diff --git a/src/value-generators/arc4.ts b/src/value-generators/arc4.ts new file mode 100644 index 0000000..e9df2ad --- /dev/null +++ b/src/value-generators/arc4.ts @@ -0,0 +1,114 @@ +import { 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 { AvmValueGenerator } from './avm' + +export class Arc4ValueGenerator { + /** + * Generate a random Algorand address. + * @returns: A new, random Algorand address. + * */ + address(): arc4.Address { + const source = new AvmValueGenerator().account() + const result = new AddressImpl({ name: 'StaticArray', genericArgs: { elementType: { name: 'Byte' }, size: { name: '32' } } }, source) + return result + } + + /** + * 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. + * @returns: A random UintN8 value. + * */ + uintN8(minValue = 0, maxValue = MAX_UINT8): arc4.UintN8 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '8' }] }, getRandomNumber(minValue, maxValue)) + } + + /** + * 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. + * @returns: A random UintN16 value. + * */ + uintN16(minValue = 0, maxValue = MAX_UINT16): arc4.UintN16 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '16' }] }, getRandomNumber(minValue, maxValue)) + } + + /** + * 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. + * @returns: A random UintN32 value. + * */ + uintN32(minValue = 0, maxValue = MAX_UINT32): arc4.UintN32 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '32' }] }, getRandomNumber(minValue, maxValue)) + } + + /** + * 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. + * @returns: A random UintN64 value. + * */ + uintN64(minValue = 0, maxValue = MAX_UINT64): arc4.UintN64 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '64' }] }, getRandomBigInt(minValue, maxValue)) + } + + /** + * 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. + * @returns: A random UintN128 value. + * */ + uintN128(minValue = 0, maxValue = MAX_UINT128): arc4.UintN128 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '128' }] }, getRandomBigInt(minValue, maxValue)) + } + + /** + * 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. + * @returns: A random UintN256 value. + * */ + uintN256(minValue = 0, maxValue = MAX_UINT256): arc4.UintN256 { + return new UintNImpl({ name: 'UintN', genericArgs: [{ name: '256' }] }, getRandomBigInt(minValue, maxValue)) + } + + /** + * 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. + * @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)) + } + + /** + * Generate a random dynamic bytes of size `n` bits. + * @param n: The number of bits for the dynamic bytes. Must be a multiple of 8, otherwise + * the last byte will be truncated. + * @returns: A new, random dynamic bytes of size `n` bits. + * */ + dynamicBytes(n: number): arc4.DynamicBytes { + return new DynamicBytesImpl( + { name: 'DynamicArray', genericArgs: { elementType: { name: 'Byte' } } }, + getRandomBytes(n / BITS_IN_BYTE).asAlgoTs(), + ) + } + + /** + * Generate a random dynamic string of size `n` bits. + * @param n: The number of bits for the string. + * @returns: A new, random string of size `n` bits. + * */ + str(n: number): arc4.Str { + // Calculate the number of characters needed (rounding up) + const numChars = n + 7 // 8 + + // Generate random string + const bytes = getRandomBytes(numChars) + return new StrImpl(JSON.stringify(undefined), bytes.toString()) + } +} diff --git a/src/value-generators/index.ts b/src/value-generators/index.ts index ad3fe82..f077945 100644 --- a/src/value-generators/index.ts +++ b/src/value-generators/index.ts @@ -1,11 +1,14 @@ +import { Arc4ValueGenerator } from './arc4' import { AvmValueGenerator } from './avm' import { TxnValueGenerator } from './txn' export class ValueGenerator extends AvmValueGenerator { txn: TxnValueGenerator + arc4: Arc4ValueGenerator constructor() { super() this.txn = new TxnValueGenerator() + this.arc4 = new Arc4ValueGenerator() } } From 2da18f4abc3f5195d4348d57c1e678b3fdfb9bed Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Sun, 22 Dec 2024 12:13:09 +0800 Subject: [PATCH 73/85] chore: update puya-ts and algo-ts versions --- package-lock.json | 10 +++++----- package.json | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 793bb2c..8235042 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "1.0.0", "hasInstallScript": true, "dependencies": { - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.22", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.34", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.23", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.35", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", @@ -73,9 +73,9 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.22", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.22.tgz", - "integrity": "sha512-RhPxX2wU3srIEmA8EgjEbE8lJQqJrUW78aKS2VnpVS/uejHMDDt+kQIjtjpNEB+vxli8shaBYZ8TM0h1wE5b0g==", + "version": "0.0.1-alpha.23", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.23.tgz", + "integrity": "sha512-hK1rom4MD2qn3tO03Bsui8lcuA7WF5CeFGdUCIrRJgc+wLnWKNx0s9TkAotrl8VwfD5Wg7Gn3u9txz4RgdQsPw==", "peerDependencies": { "tslib": "^2.6.2" } diff --git a/package.json b/package.json index 513f04a..0e2b138 100644 --- a/package.json +++ b/package.json @@ -63,8 +63,8 @@ "tslib": "^2.6.2" }, "dependencies": { - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.22", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.34", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.23", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.35", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", From 3db1ac14a56c8aacf58a2caeb0d5bbcec170ad7c Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Sun, 22 Dec 2024 16:13:34 +0800 Subject: [PATCH 74/85] feat: implement stubs for decodeArc4 and encodeArc4 functions --- src/impl/encoded-types.ts | 132 +++++++++++++++++++++++--- src/impl/transactions.ts | 9 ++ src/runtime-helpers.ts | 1 + src/test-transformer/node-factory.ts | 10 +- src/test-transformer/visitors.ts | 11 ++- src/value-generators/arc4.ts | 7 +- tests/arc4/encode-decode-arc4.spec.ts | 130 +++++++++++++++++++++++++ 7 files changed, 281 insertions(+), 19 deletions(-) create mode 100644 tests/arc4/encode-decode-arc4.spec.ts diff --git a/src/impl/encoded-types.ts b/src/impl/encoded-types.ts index a9a7d26..9ff4bfa 100644 --- a/src/impl/encoded-types.ts +++ b/src/impl/encoded-types.ts @@ -24,14 +24,20 @@ import { BITS_IN_BYTE, UINT64_SIZE, } from '../constants' +import { lazyContext } from '../context-helpers/internal-context' import { fromBytes, TypeInfo } from '../encoders' import { DeliberateAny } from '../typescript-helpers' -import { asBigUint, asBigUintCls, asBytesCls, asUint64, asUint8Array, conactUint8Arrays, uint8ArrayToNumber } from '../util' +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' 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)) + type CompatForArc4Int = N extends 8 | 16 | 32 | 64 ? Uint64Compat : BigUintCompat export class UintNImpl extends UintN { private value: Uint8Array @@ -99,7 +105,7 @@ export class UFixedNxMImpl extends UFixedNx private value: Uint8Array private bitSize: N private precision: M - private typeInfo: TypeInfo + typeInfo: TypeInfo constructor(typeInfo: TypeInfo | string, v: `${number}.${number}`) { super(v) @@ -163,7 +169,10 @@ export class UFixedNxMImpl extends UFixedNx export class ByteImpl extends Byte { private value: UintNImpl<8> - constructor(typeInfo: TypeInfo | string, v?: CompatForArc4Int<8>) { + constructor( + public typeInfo: TypeInfo | string, + v?: CompatForArc4Int<8>, + ) { super(v) this.value = new UintNImpl<8>(typeInfo, v) } @@ -202,7 +211,10 @@ export class ByteImpl extends Byte { export class StrImpl extends Str { private value: Uint8Array - constructor(_typeInfo: TypeInfo | string, s?: StringCompat) { + constructor( + public typeInfo: TypeInfo | string, + s?: StringCompat, + ) { super() const bytesValue = asBytesCls(s ?? '') const bytesLength = encodeLength(bytesValue.length.asNumber()) @@ -244,7 +256,10 @@ const FALSE_BIGINT_VALUE = 0n export class BoolImpl extends Bool { private value: Uint8Array - constructor(_typeInfo: TypeInfo | string, v?: boolean) { + constructor( + public typeInfo: TypeInfo | string, + v?: boolean, + ) { super(v) this.value = encodingUtil.bigIntToUint8Array(v ? TRUE_BIGINT_VALUE : FALSE_BIGINT_VALUE, 1) } @@ -320,8 +335,8 @@ const arrayProxyHandler = () => ({ export class StaticArrayImpl extends StaticArray { private value?: TItem[] private uint8ArrayValue?: Uint8Array - private typeInfo: TypeInfo private size: number + typeInfo: TypeInfo genericArgs: StaticArrayGenericArgs constructor(typeInfo: TypeInfo | string, ...items: TItem[] & { length: TLength }) @@ -383,6 +398,10 @@ export class StaticArrayImpl return StaticArrayImpl.fromBytesImpl(this.bytes, JSON.stringify(this.typeInfo)) as StaticArrayImpl } + get native(): TItem[] { + return this.items + } + static fromBytesImpl( value: internal.primitives.StubBytesCompat | Uint8Array, typeInfo: string | TypeInfo, @@ -425,7 +444,7 @@ export class StaticArrayImpl } export class AddressImpl extends Address { - private typeInfo: TypeInfo + typeInfo: TypeInfo private value: StaticArrayImpl constructor(typeInfo: TypeInfo | string, value?: Account | string | bytes) { @@ -499,7 +518,7 @@ const readLength = (value: Uint8Array): readonly [number, Uint8Array] => { export class DynamicArrayImpl extends DynamicArray { private value?: TItem[] private uint8ArrayValue?: Uint8Array - private typeInfo: TypeInfo + typeInfo: TypeInfo genericArgs: DynamicArrayGenericArgs constructor(typeInfo: TypeInfo | string, ...items: TItem[]) { @@ -554,6 +573,10 @@ export class DynamicArrayImpl extends DynamicArray } + get native(): TItem[] { + return this.items + } + push(...values: TItem[]) { const items = this.items items.push(...values) @@ -594,7 +617,7 @@ export class DynamicArrayImpl extends DynamicArray extends Tuple { private value?: TTuple private uint8ArrayValue?: Uint8Array - private typeInfo: TypeInfo + typeInfo: TypeInfo genericArgs: TypeInfo[] constructor(typeInfo: TypeInfo | string) @@ -691,7 +714,6 @@ export class TupleImpl extends T type StructConstraint = Record export class StructImpl extends (Struct as DeliberateAny) { private uint8ArrayValue?: Uint8Array - private typeInfo: TypeInfo genericArgs: Record constructor(typeInfo: TypeInfo | string, value: T = {} as T) { @@ -737,6 +759,10 @@ export class StructImpl extends (Struct extends (Struct constructor(typeInfo: TypeInfo | string, value?: bytes | string) { @@ -825,7 +851,7 @@ export class DynamicBytesImpl extends DynamicBytes { export class StaticBytesImpl extends StaticBytes { private value: StaticArrayImpl - private typeInfo: TypeInfo + typeInfo: TypeInfo constructor(typeInfo: TypeInfo | string, value?: bytes | string) { super(value) @@ -1161,3 +1187,85 @@ export const getArc4TypeName = (typeInfo: TypeInfo): string | undefined => { else if (typeof name === 'function') return name(typeInfo) return undefined } + +export function decodeArc4Impl(sourceTypeInfoString: string, bytes: internal.primitives.StubBytesCompat): T { + const sourceTypeInfo = JSON.parse(sourceTypeInfoString) + const encoder = getArc4Encoder(sourceTypeInfo) + const source = encoder(bytes, sourceTypeInfo) + + return getNativeValue(source) as T +} + +export function encodeArc4Impl(_targetTypeInfoString: string, source: T): bytes { + const arc4Encoded = getArc4Encoded(source) + return arc4Encoded.bytes +} + +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) { + return native + } else if (typeof native === 'object') { + return Object.fromEntries(Object.entries(native).map(([key, value]) => [key, getNativeValue(value)])) + } + return native +} + +const getArc4Encoded = (value: DeliberateAny): ARC4Encoded => { + if (value instanceof ARC4Encoded) { + return value + } + if (value instanceof AccountCls) { + const index = (lazyContext.activeGroup.activeTransaction as ApplicationTransaction).apat.indexOf(value) + return new UintNImpl({ name: 'UintN<64>', genericArgs: [{ name: '64' }] }, asBigInt(index)) + } + if (value instanceof AssetCls) { + const index = (lazyContext.activeGroup.activeTransaction as ApplicationTransaction).apas.indexOf(value) + return new UintNImpl({ name: 'UintN<64>', genericArgs: [{ name: '64' }] }, asBigInt(index)) + } + if (value instanceof ApplicationCls) { + const index = (lazyContext.activeGroup.activeTransaction as ApplicationTransaction).apfa.indexOf(value) + return new UintNImpl({ name: 'UintN<64>', genericArgs: [{ name: '64' }] }, asBigInt(index)) + } + if (typeof value === 'boolean') { + return new BoolImpl({ name: 'Bool' }, value) + } + if (value instanceof internal.primitives.Uint64Cls || typeof value === 'number') { + return new UintNImpl({ name: 'UintN<64>', genericArgs: [{ name: '64' }] }, asBigInt(value)) + } + if (value instanceof internal.primitives.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) { + return new DynamicBytesImpl( + { name: 'DynamicBytes', genericArgs: { elementType: { name: 'Byte', genericArgs: [{ name: '8' }] } } }, + value.asAlgoTs(), + ) + } + if (typeof value === 'string') { + return new StrImpl({ name: 'Str' }, value) + } + if (Array.isArray(value)) { + const result: ARC4Encoded[] = value.reduce((acc: ARC4Encoded[], cur: DeliberateAny) => { + return acc.concat(getArc4Encoded(cur)) + }, []) + const genericArgs: TypeInfo[] = result.map((x) => (x as DeliberateAny).typeInfo) + const typeInfo = { name: `Tuple<[${genericArgs.map((x) => x.name).join(',')}]>`, genericArgs } + return new TupleImpl(typeInfo, ...(result as [])) + } + if (typeof value === 'object') { + const result = Object.values(value).reduce((acc: ARC4Encoded[], cur: DeliberateAny) => { + return acc.concat(getArc4Encoded(cur)) + }, []) + const genericArgs: TypeInfo[] = result.map((x) => (x as DeliberateAny).typeInfo) + const typeInfo = { name: 'Struct', genericArgs: Object.fromEntries(Object.keys(value).map((x, i) => [x, genericArgs[i]])) } + 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}`) +} diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index 6e0b85e..fda0abd 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -307,6 +307,15 @@ export class ApplicationTransaction extends TransactionBase implements gtxn.Appl get lastLog() { return this.#appLogs.at(-1) ?? lazyContext.getApplicationData(this.appId.id).appLogs.at(-1) ?? Bytes() } + get apat() { + return this.#accounts + } + get apas() { + return this.#assets + } + get apfa() { + return this.#apps + } appArgs(index: internal.primitives.StubUint64Compat): bytes { return toBytes(this.#appArgs[asNumber(index)]) } diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 48b08d6..82aab27 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -8,6 +8,7 @@ import { nameOfType } from './util' export { attachAbiMetadata } from './abi-metadata' export * from './impl/encoded-types' +export { decodeArc4Impl, encodeArc4Impl } from './impl/encoded-types' export { ensureBudgetImpl } from './impl/ensure-budget' export { TemplateVarImpl } from './impl/template-var' diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 684c734..faec9ad 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -94,17 +94,19 @@ export const nodeFactory = { ) }, - callStubbedFunction(functionName: string, node: ts.CallExpression, typeInfo?: TypeInfo) { - const infoString = JSON.stringify(typeInfo) + callStubbedFunction(functionName: string, node: ts.CallExpression, ...typeInfos: (TypeInfo | undefined)[]) { + const infoStringArray = typeInfos.length ? typeInfos.map((typeInfo) => JSON.stringify(typeInfo)) : undefined const updatedPropertyAccessExpression = factory.createPropertyAccessExpression( factory.createIdentifier('runtimeHelpers'), `${functionName}Impl`, ) - + const typeInfoArgs = infoStringArray + ? infoStringArray?.filter((s) => !!s).map((infoString) => factory.createStringLiteral(infoString)) + : undefined return factory.createCallExpression( updatedPropertyAccessExpression, node.typeArguments, - [infoString ? factory.createStringLiteral(infoString) : undefined, ...(node.arguments ?? [])].filter((arg) => !!arg), + [...(typeInfoArgs ?? []), ...(node.arguments ?? [])].filter((arg) => !!arg), ) }, } satisfies Record ts.Node> diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index 8275563..d621436 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -111,7 +111,13 @@ class ExpressionVisitor { } if (ts.isCallExpression(updatedNode)) { const stubbedFunctionName = tryGetStubbedFunctionName(updatedNode, this.helper) - updatedNode = stubbedFunctionName ? nodeFactory.callStubbedFunction(stubbedFunctionName, updatedNode, info) : updatedNode + const infos = [info] + if (isCallingDecodeArc4(stubbedFunctionName)) { + const targetType = ptypes.ptypeToArc4EncodedType(type, this.helper.sourceLocation(node)) + const targetTypeInfo = getGenericTypeInfo(targetType) + infos[0] = targetTypeInfo + } + updatedNode = stubbedFunctionName ? nodeFactory.callStubbedFunction(stubbedFunctionName, updatedNode, ...infos) : updatedNode } return isGeneric ? nodeFactory.captureGenericTypeInfo(ts.visitEachChild(updatedNode, this.visit, this.context), JSON.stringify(info)) @@ -289,6 +295,7 @@ const isGenericType = (type: ptypes.PType): boolean => ptypes.StaticArrayType, ptypes.UFixedNxMType, ptypes.UintNType, + ptypes.TuplePType, ) const isArc4EncodedType = (type: ptypes.PType): boolean => @@ -356,3 +363,5 @@ const tryGetStubbedFunctionName = (node: ts.CallExpression, helper: VisitorHelpe const stubbedFunctionNames = ['interpretAsArc4', 'decodeArc4', 'encodeArc4', 'TemplateVar', 'ensureBudget'] return stubbedFunctionNames.includes(functionName) ? functionName : undefined } + +const isCallingDecodeArc4 = (functionName: string | undefined): boolean => ['decodeArc4', 'encodeArc4'].includes(functionName ?? '') diff --git a/src/value-generators/arc4.ts b/src/value-generators/arc4.ts index e9df2ad..9b16093 100644 --- a/src/value-generators/arc4.ts +++ b/src/value-generators/arc4.ts @@ -11,7 +11,10 @@ export class Arc4ValueGenerator { * */ address(): arc4.Address { const source = new AvmValueGenerator().account() - const result = new AddressImpl({ name: 'StaticArray', genericArgs: { elementType: { name: 'Byte' }, size: { name: '32' } } }, source) + const result = new AddressImpl( + { name: 'StaticArray', genericArgs: { elementType: { name: 'Byte', genericArgs: [{ name: '8' }] }, size: { name: '32' } } }, + source, + ) return result } @@ -93,7 +96,7 @@ export class Arc4ValueGenerator { * */ dynamicBytes(n: number): arc4.DynamicBytes { return new DynamicBytesImpl( - { name: 'DynamicArray', genericArgs: { elementType: { name: 'Byte' } } }, + { name: 'DynamicBytes', genericArgs: { elementType: { name: 'Byte', genericArgs: [{ name: '8' }] } } }, getRandomBytes(n / BITS_IN_BYTE).asAlgoTs(), ) } diff --git a/tests/arc4/encode-decode-arc4.spec.ts b/tests/arc4/encode-decode-arc4.spec.ts new file mode 100644 index 0000000..bf368fc --- /dev/null +++ b/tests/arc4/encode-decode-arc4.spec.ts @@ -0,0 +1,130 @@ +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 { describe, expect, test } from 'vitest' +import { MAX_UINT128 } from '../../src/constants' +import { DeliberateAny } from '../../src/typescript-helpers' +import { asBytes } from '../../src/util' + +const nativeString = 'hello' +const nativeNumber = 42 +const nativeBigInt = MAX_UINT128 +const nativeBool = true +const nativeBytes = Bytes('hello') + +const abiString = new Str('hello') +const abiUint64 = new UintN<64>(42) +const abiUint512 = new UintN<512>(MAX_UINT128) +const abiBool = new Bool(true) +const abiBytes = new DynamicBytes(Bytes('hello')) + +class Swapped1 extends Struct<{ + b: UintN<64> + c: Bool + d: Str + a: Tuple<[UintN<64>, Bool, Bool]> +}> {} + +const testData = [ + { + nativeValues() { + return [nativeNumber, nativeNumber, nativeBigInt, nativeBytes] + }, + abiValues() { + return [abiUint64, abiUint64, abiUint512, abiBytes] as readonly [UintN<64>, UintN<64>, UintN<512>, DynamicBytes] + }, + arc4Value() { + return new Tuple<[UintN<64>, UintN<64>, UintN<512>, DynamicBytes]>(abiUint64, abiUint64, abiUint512, abiBytes) + }, + decode(value: internal.primitives.StubBytesCompat) { + return decodeArc4<[uint64, uint64, biguint, bytes]>(asBytes(value)) + }, + }, + { + nativeValues() { + return [ + [nativeBool, [nativeString, nativeBool]], + [nativeNumber, nativeNumber], + [nativeBigInt, nativeBytes, { b: nativeNumber, c: nativeBool, d: nativeString, a: [nativeNumber, nativeBool, nativeBool] }], + ] + }, + abiValues() { + return [ + new Tuple<[Bool, Tuple<[Str, Bool]>]>(abiBool, new Tuple<[Str, Bool]>(abiString, abiBool)), + new Tuple<[UintN<64>, UintN<64>]>(abiUint64, abiUint64), + new Tuple<[UintN<512>, DynamicBytes, Swapped1]>( + abiUint512, + abiBytes, + new Swapped1({ b: abiUint64, c: abiBool, d: abiString, a: new Tuple<[UintN<64>, Bool, Bool]>(abiUint64, abiBool, abiBool) }), + ), + ] as readonly [Tuple<[Bool, Tuple<[Str, Bool]>]>, Tuple<[UintN<64>, UintN<64>]>, Tuple<[UintN<512>, DynamicBytes, Swapped1]>] + }, + arc4Value() { + return new Tuple<[Tuple<[Bool, Tuple<[Str, Bool]>]>, Tuple<[UintN<64>, UintN<64>]>, Tuple<[UintN<512>, DynamicBytes, Swapped1]>]>( + ...this.abiValues(), + ) + }, + decode(value: internal.primitives.StubBytesCompat) { + return decodeArc4< + [ + [boolean, [string, boolean]], + [uint64, uint64], + [ + biguint, + bytes, + { + b: uint64 + c: boolean + d: string + a: [uint64, boolean, boolean] + }, + ], + ] + >(asBytes(value)) + }, + }, + { + nativeValues() { + return { b: nativeNumber, c: nativeBool, d: nativeString, a: [nativeNumber, nativeBool, nativeBool] } + }, + abiValues() { + return { b: abiUint64, c: abiBool, d: abiString, a: new Tuple<[UintN<64>, Bool, Bool]>(abiUint64, abiBool, abiBool) } + }, + arc4Value() { + return new Swapped1(this.abiValues()) + }, + decode(value: internal.primitives.StubBytesCompat) { + return decodeArc4<{ b: uint64; c: boolean; d: string; a: [uint64, boolean, boolean] }>(asBytes(value)) + }, + }, +] + +describe('decodeArc4', () => { + test.each(testData)('should decode ABI values', (data) => { + const nativeValues = data.nativeValues() + const arc4Value = data.arc4Value() + + const result = data.decode(arc4Value.bytes) + + compareNativeValues(result, nativeValues) + }) +}) + +describe('encodeArc4', () => { + test.each(testData)('should encode native values', (data) => { + const nativeValues = data.nativeValues() + const arc4Value = data.arc4Value() + + const result = encodeArc4(nativeValues) + + expect(result).toEqual(arc4Value.bytes) + }) +}) + +const compareNativeValues = (a: DeliberateAny, b: DeliberateAny) => { + if (Array.isArray(a)) { + for (let i = 0; i < a.length; i++) { + compareNativeValues(a[i], b[i]) + } + } + expect(a).toEqual(b) +} From 73dd3e7c9aec8a5744581c5f9a2d57b3940aa80c Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 23 Dec 2024 11:35:34 +0800 Subject: [PATCH 75/85] chore: update puya-ts package version --- package-lock.json | 237 ++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 112 insertions(+), 127 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8235042..c224f49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "dependencies": { "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.23", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.35", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.36", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", @@ -81,9 +81,9 @@ } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-beta.2.tgz", - "integrity": "sha512-kHIWCOmsU18ceLMKrzTa6Q4hfHp7+Ai58rcxdqNNKtDfzvffWuPLI6oMP2gj6wP+ZTrIdoLNGMhJVOlvtCYpew==", + "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" ], @@ -1644,9 +1644,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", - "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==", + "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==", "cpu": [ "arm" ], @@ -1658,9 +1658,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz", - "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==", + "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==", "cpu": [ "arm64" ], @@ -1672,9 +1672,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz", - "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz", + "integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==", "cpu": [ "arm64" ], @@ -1686,9 +1686,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz", - "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==", + "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==", "cpu": [ "x64" ], @@ -1700,9 +1700,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz", - "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==", + "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==", "cpu": [ "arm64" ], @@ -1714,9 +1714,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz", - "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==", + "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==", "cpu": [ "x64" ], @@ -1728,9 +1728,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz", - "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==", + "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==", "cpu": [ "arm" ], @@ -1742,9 +1742,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz", - "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==", + "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==", "cpu": [ "arm" ], @@ -1756,9 +1756,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz", - "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==", + "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==", "cpu": [ "arm64" ], @@ -1770,9 +1770,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz", - "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==", + "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==", "cpu": [ "arm64" ], @@ -1784,9 +1784,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz", - "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==", + "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==", "cpu": [ "loong64" ], @@ -1798,9 +1798,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz", - "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==", + "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==", "cpu": [ "ppc64" ], @@ -1812,9 +1812,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz", - "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==", + "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==", "cpu": [ "riscv64" ], @@ -1826,9 +1826,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz", - "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==", + "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==", "cpu": [ "s390x" ], @@ -1840,9 +1840,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz", - "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==", + "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==", "cpu": [ "x64" ], @@ -1854,9 +1854,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz", - "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==", + "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==", "cpu": [ "x64" ], @@ -1868,9 +1868,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz", - "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==", + "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==", "cpu": [ "arm64" ], @@ -1882,9 +1882,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz", - "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==", + "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==", "cpu": [ "ia32" ], @@ -1896,9 +1896,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz", - "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==", + "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==", "cpu": [ "x64" ], @@ -3240,9 +3240,9 @@ } }, "node_modules/chalk": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.0.tgz", - "integrity": "sha512-ZkD35Mx92acjB2yNJgziGqT9oKHEOxjTBTDRpOsRWtdecL/0jM3z5kM/CTzHWvHIen1GvkM85p6TuFfDGfc8/Q==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -4573,28 +4573,28 @@ } }, "node_modules/es-abstract": { - "version": "1.23.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.6.tgz", - "integrity": "sha512-Ifco6n3yj2tMZDWNLyloZrytt9lqqlwvS83P3HtaETR0NUOYnIULGGHpktqYGObGy+8wc1okO25p8TjemhImvA==", + "version": "1.23.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.7.tgz", + "integrity": "sha512-OygGC8kIcDhXX+6yAZRGLqwi2CmEXCbLQixeGUgYeR+Qwlppqmo7DIDr8XibtEBZp+fJcoYpoatp5qwLMEdcqQ==", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", + "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.3", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.7", + "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.2.6", - "get-symbol-description": "^1.0.2", + "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", @@ -4602,31 +4602,30 @@ "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.4", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", - "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", - "is-shared-array-buffer": "^1.0.3", + "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", - "is-typed-array": "^1.1.13", + "is-typed-array": "^1.1.15", "is-weakref": "^1.1.0", - "math-intrinsics": "^1.0.0", + "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", + "object.assign": "^4.1.7", "regexp.prototype.flags": "^1.5.3", "safe-array-concat": "^1.1.3", "safe-regex-test": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.3", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.16" + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" }, "engines": { "node": ">= 0.4" @@ -6380,9 +6379,9 @@ } }, "node_modules/is-core-module": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz", - "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { @@ -6530,19 +6529,6 @@ "dev": true, "license": "MIT" }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -6997,9 +6983,9 @@ "license": "MIT" }, "node_modules/json-stable-stringify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.2.0.tgz", - "integrity": "sha512-ex8jk9BZHBolvbd5cRnAgwyaYcYB0qZldy1e+LCOdcF6+AUmVZ6LcGUMzsRTW83QMeu+GxZGrcLqxqrgfXGvIw==", + "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": { @@ -11743,9 +11729,9 @@ } }, "node_modules/rollup": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz", - "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz", + "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==", "dev": true, "license": "MIT", "dependencies": { @@ -11759,25 +11745,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.28.1", - "@rollup/rollup-android-arm64": "4.28.1", - "@rollup/rollup-darwin-arm64": "4.28.1", - "@rollup/rollup-darwin-x64": "4.28.1", - "@rollup/rollup-freebsd-arm64": "4.28.1", - "@rollup/rollup-freebsd-x64": "4.28.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.28.1", - "@rollup/rollup-linux-arm-musleabihf": "4.28.1", - "@rollup/rollup-linux-arm64-gnu": "4.28.1", - "@rollup/rollup-linux-arm64-musl": "4.28.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.28.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1", - "@rollup/rollup-linux-riscv64-gnu": "4.28.1", - "@rollup/rollup-linux-s390x-gnu": "4.28.1", - "@rollup/rollup-linux-x64-gnu": "4.28.1", - "@rollup/rollup-linux-x64-musl": "4.28.1", - "@rollup/rollup-win32-arm64-msvc": "4.28.1", - "@rollup/rollup-win32-ia32-msvc": "4.28.1", - "@rollup/rollup-win32-x64-msvc": "4.28.1", + "@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", "fsevents": "~2.3.2" } }, @@ -13262,7 +13248,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", - "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 0e2b138..1996da5 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ }, "dependencies": { "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.23", - "@algorandfoundation/puya-ts": "^1.0.0-alpha.35", + "@algorandfoundation/puya-ts": "^1.0.0-alpha.36", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", From 79838c7efd34dcd8129f8dd43a20f282bad995ee Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 23 Dec 2024 18:02:51 +0800 Subject: [PATCH 76/85] feat: implement stub for emit function --- src/abi-metadata.ts | 2 +- src/impl/emit.ts | 28 + src/impl/encoded-types.ts | 36 +- src/runtime-helpers.ts | 1 + src/test-transformer/visitors.ts | 12 +- tests/arc4/emit.spec.ts | 138 + .../arc4-primitive-ops/contract.algo.ts | 60 +- .../Arc4PrimitiveOpsContract.approval.teal | 1229 +++++---- .../data/Arc4PrimitiveOpsContract.arc32.json | 2338 +++++++++-------- .../data/Arc4PrimitiveOpsContract.arc56.json | 803 ++++-- .../data/Arc4PrimitiveOpsContract.clear.teal | 4 +- 11 files changed, 2743 insertions(+), 1908 deletions(-) create mode 100644 src/impl/emit.ts create mode 100644 tests/arc4/emit.spec.ts diff --git a/src/abi-metadata.ts b/src/abi-metadata.ts index 9e97a2e..f31554f 100644 --- a/src/abi-metadata.ts +++ b/src/abi-metadata.ts @@ -103,7 +103,7 @@ const getArc4TypeName = (t: TypeInfo): string => { AssetTransferTxn: 'axfer', AssetFreezeTxn: 'afrz', ApplicationTxn: 'appl', - 'Tuple<.*>': (t) => + 'Tuple(<.*>)?': (t) => `(${Object.values(t.genericArgs as Record) .map(getArc4TypeName) .join(',')})`, diff --git a/src/impl/emit.ts b/src/impl/emit.ts new file mode 100644 index 0000000..d5974ed --- /dev/null +++ b/src/impl/emit.ts @@ -0,0 +1,28 @@ +import { internal } from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' +import { DeliberateAny } from '../typescript-helpers' +import { sha512_256 } from './crypto' +import { getArc4Encoded, getArc4TypeName } from './encoded-types' + +export function emitImpl(typeInfoString: string, event: T | string, ...eventProps: unknown[]) { + let eventData + let eventName + if (typeof event === 'string') { + eventData = getArc4Encoded(eventProps) + eventName = event + const argTypes = getArc4TypeName((eventData as DeliberateAny).typeInfo)! + 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}`) + } + } else { + eventData = getArc4Encoded(event) + const typeInfo = JSON.parse(typeInfoString) + const argTypes = getArc4TypeName((eventData as DeliberateAny).typeInfo)! + eventName = typeInfo.name.replace(/.*.*/, '') + argTypes + } + + const eventHash = sha512_256(eventName) + lazyContext.value.log(eventHash.slice(0, 4).concat(eventData.bytes)) +} diff --git a/src/impl/encoded-types.ts b/src/impl/encoded-types.ts index 9ff4bfa..162c5fb 100644 --- a/src/impl/encoded-types.ts +++ b/src/impl/encoded-types.ts @@ -167,13 +167,12 @@ export class UFixedNxMImpl extends UFixedNx } export class ByteImpl extends Byte { + typeInfo: TypeInfo private value: UintNImpl<8> - constructor( - public typeInfo: TypeInfo | string, - v?: CompatForArc4Int<8>, - ) { + constructor(typeInfo: TypeInfo | string, v?: CompatForArc4Int<8>) { super(v) + this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo this.value = new UintNImpl<8>(typeInfo, v) } @@ -209,15 +208,14 @@ export class ByteImpl extends Byte { } export class StrImpl extends Str { + typeInfo: TypeInfo private value: Uint8Array - constructor( - public typeInfo: TypeInfo | string, - s?: StringCompat, - ) { + constructor(typeInfo: TypeInfo | string, s?: StringCompat) { super() const bytesValue = asBytesCls(s ?? '') const bytesLength = encodeLength(bytesValue.length.asNumber()) + this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo this.value = asUint8Array(bytesLength.concat(bytesValue)) } get native(): string { @@ -255,12 +253,11 @@ const TRUE_BIGINT_VALUE = 128n const FALSE_BIGINT_VALUE = 0n export class BoolImpl extends Bool { private value: Uint8Array + typeInfo: TypeInfo - constructor( - public typeInfo: TypeInfo | string, - v?: boolean, - ) { + constructor(typeInfo: TypeInfo | string, v?: boolean) { super(v) + this.typeInfo = typeof typeInfo === 'string' ? JSON.parse(typeInfo) : typeInfo this.value = encodingUtil.bigIntToUint8Array(v ? TRUE_BIGINT_VALUE : FALSE_BIGINT_VALUE, 1) } @@ -1154,8 +1151,8 @@ export const arc4Encoders: Record> = { 'UFixedNxM<.*>': UFixedNxMImpl.fromBytesImpl, 'StaticArray<.*>': StaticArrayImpl.fromBytesImpl, 'DynamicArray<.*>': DynamicArrayImpl.fromBytesImpl, - Tuple: TupleImpl.fromBytesImpl, - Struct: StructImpl.fromBytesImpl, + 'Tuple(<.*>)?': TupleImpl.fromBytesImpl, + 'Struct(<.*>)?': StructImpl.fromBytesImpl, DynamicBytes: DynamicBytesImpl.fromBytesImpl, 'StaticBytes<.*>': StaticBytesImpl.fromBytesImpl, } @@ -1177,8 +1174,8 @@ export const getArc4TypeName = (typeInfo: TypeInfo): string | undefined => { 'UFixedNxM<.*>': UFixedNxMImpl.getArc4TypeName, 'StaticArray<.*>': StaticArrayImpl.getArc4TypeName, 'DynamicArray<.*>': DynamicArrayImpl.getArc4TypeName, - Tuple: TupleImpl.getArc4TypeName, - Struct: StructImpl.getArc4TypeName, + 'Tuple(<.*>)?': TupleImpl.getArc4TypeName, + 'Struct(<.*>)?': StructImpl.getArc4TypeName, DynamicBytes: DynamicBytesImpl.getArc4TypeName, 'StaticBytes<.*>': StaticBytesImpl.getArc4TypeName, } @@ -1213,7 +1210,7 @@ const getNativeValue = (value: DeliberateAny): DeliberateAny => { return native } -const getArc4Encoded = (value: DeliberateAny): ARC4Encoded => { +export const getArc4Encoded = (value: DeliberateAny): ARC4Encoded => { if (value instanceof ARC4Encoded) { return value } @@ -1263,7 +1260,10 @@ const getArc4Encoded = (value: DeliberateAny): ARC4Encoded => { return acc.concat(getArc4Encoded(cur)) }, []) const genericArgs: TypeInfo[] = result.map((x) => (x as DeliberateAny).typeInfo) - const typeInfo = { name: 'Struct', genericArgs: Object.fromEntries(Object.keys(value).map((x, i) => [x, genericArgs[i]])) } + const typeInfo = { + name: `Struct<${value.constructor.name}>`, + genericArgs: Object.fromEntries(Object.keys(value).map((x, i) => [x, genericArgs[i]])), + } return new StructImpl(typeInfo, Object.fromEntries(Object.keys(value).map((x, i) => [x, result[i]]))) } diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 82aab27..a620884 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -7,6 +7,7 @@ import { DeliberateAny } from './typescript-helpers' import { nameOfType } from './util' export { attachAbiMetadata } from './abi-metadata' +export { emitImpl } from './impl/emit' export * from './impl/encoded-types' export { decodeArc4Impl, encodeArc4Impl } from './impl/encoded-types' export { ensureBudgetImpl } from './impl/ensure-budget' diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index d621436..fd686ae 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -21,6 +21,7 @@ const algotsModulePaths = [ type VisitorHelper = { additionalStatements: ts.Statement[] resolveType(node: ts.Node): ptypes.PType + resolveTypeParameters(node: ts.CallExpression): ptypes.PType[] sourceLocation(node: ts.Node): SourceLocation tryGetSymbol(node: ts.Node): ts.Symbol | undefined } @@ -44,6 +45,9 @@ export class SourceFileVisitor { return ptypes.anyPType } }, + resolveTypeParameters(node: ts.CallExpression) { + return typeResolver.resolveTypeParameters(node, this.sourceLocation(node)) + }, tryGetSymbol(node: ts.Node): ts.Symbol | undefined { const s = typeChecker.getSymbolAtLocation(node) return s && s.flags & ts.SymbolFlags.Alias ? typeChecker.getAliasedSymbol(s) : s @@ -112,6 +116,9 @@ class ExpressionVisitor { if (ts.isCallExpression(updatedNode)) { const stubbedFunctionName = tryGetStubbedFunctionName(updatedNode, this.helper) const infos = [info] + if (isCallingEmit(stubbedFunctionName)) { + infos[0] = this.helper.resolveTypeParameters(updatedNode).map(getGenericTypeInfo)[0] + } if (isCallingDecodeArc4(stubbedFunctionName)) { const targetType = ptypes.ptypeToArc4EncodedType(type, this.helper.sourceLocation(node)) const targetTypeInfo = getGenericTypeInfo(targetType) @@ -332,7 +339,7 @@ const getGenericTypeInfo = (type: ptypes.PType): TypeInfo => { } else if (type instanceof ptypes.UintNType) { genericArgs.push({ name: type.n.toString() }) } else if (type instanceof ptypes.ARC4StructType) { - typeName = 'Struct' + typeName = `Struct<${type.name}>` genericArgs = Object.fromEntries( Object.entries(type.fields) .map(([key, value]) => [key, getGenericTypeInfo(value)]) @@ -360,8 +367,9 @@ 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'] + const stubbedFunctionNames = ['interpretAsArc4', 'decodeArc4', 'encodeArc4', 'TemplateVar', 'ensureBudget', 'emit'] return stubbedFunctionNames.includes(functionName) ? functionName : undefined } const isCallingDecodeArc4 = (functionName: string | undefined): boolean => ['decodeArc4', 'encodeArc4'].includes(functionName ?? '') +const isCallingEmit = (functionName: string | undefined): boolean => 'emit' === (functionName ?? '') diff --git a/tests/arc4/emit.spec.ts b/tests/arc4/emit.spec.ts new file mode 100644 index 0000000..be5af0b --- /dev/null +++ b/tests/arc4/emit.spec.ts @@ -0,0 +1,138 @@ +import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import { arc4, BigUint, biguint, Bytes, bytes, emit, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, expect, it } 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 { asBigUintCls, asNumber, asUint8Array } from '../../src/util' + +class Swapped { + a: string + b: biguint + c: uint64 + d: bytes + e: uint64 + f: boolean + g: bytes + h: string + + constructor(a: string, b: biguint, c: uint64, d: bytes, e: uint64, f: boolean, g: bytes, h: string) { + this.a = a + this.b = b + this.c = c + this.d = d + this.e = e + this.f = f + this.g = g + this.h = h + } +} +class SwappedArc4 extends arc4.Struct<{ + m: arc4.UintN<64> + n: arc4.UintN<256> + o: arc4.UFixedNxM<32, 8> + p: arc4.UFixedNxM<256, 16> + q: arc4.Bool + r: arc4.StaticArray + s: arc4.DynamicArray + t: arc4.Tuple<[arc4.UintN32, arc4.UintN64, arc4.Str]> +}> {} + +describe('arc4.emit', async () => { + const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) + const ctx = new TestExecutionContext() + + afterEach(async () => { + ctx.reset() + }) + + it('should emit the correct values', async () => { + 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({ + m: new arc4.UintN64(42), + n: new arc4.UintN256(512), + o: new arc4.UFixedNxM<32, 8>('42.94967295'), + p: new arc4.UFixedNxM<256, 16>('25.5'), + q: new arc4.Bool(true), + r: new arc4.StaticArray(new arc4.UintN8(1), new arc4.UintN8(2), new arc4.UintN8(3)), + s: new arc4.DynamicArray(new arc4.UintN16(1), new arc4.UintN16(2), new arc4.UintN16(3)), + t: new arc4.Tuple(new arc4.UintN32(1), new arc4.UintN64(2), new arc4.Str('hello')), + }) + const avm_result = await getAvmResultLog( + { appClient }, + 'verify_emit', + test_data.a, + test_data.b.valueOf(), + test_data.c.valueOf(), + asUint8Array(test_data.d), + test_data.e, + test_data.f, + asUint8Array(test_data.g), + test_data.h, + test_data_arc4.m.native.valueOf(), + test_data_arc4.n.native.valueOf(), + asBigUintCls(test_data_arc4.o.bytes).asBigInt(), + asBigUintCls(test_data_arc4.p.bytes).asBigInt(), + test_data_arc4.q.native, + asUint8Array(test_data_arc4.r.bytes), + asUint8Array(test_data_arc4.s.bytes), + asUint8Array(test_data_arc4.t.bytes), + ) + + expect(avm_result).toBeInstanceOf(Array) + const avmLogs = avm_result?.map(Bytes) + + const dummy_app = ctx.any.application() + const app_txn = ctx.any.txn.applicationCall({ appId: dummy_app }) + ctx.txn.createScope([app_txn]).execute(() => { + emit(test_data_arc4) + emit( + 'Swapped', + test_data.a, + test_data.b, + test_data.c, + test_data.d, + test_data.e, + test_data.f, + test_data.g, + test_data.h, + test_data_arc4.m, + test_data_arc4.n, + test_data_arc4.o, + test_data_arc4.p, + test_data_arc4.q, + test_data_arc4.r, + test_data_arc4.s, + test_data_arc4.t, + ) + emit( + 'Swapped(string,uint512,uint64,byte[],uint64,bool,byte[],string,uint64,uint256,ufixed32x8,ufixed256x16,bool,uint8[3],uint16[],(uint32,uint64,string))', + test_data.a, + test_data.b, + test_data.c, + test_data.d, + test_data.e, + test_data.f, + test_data.g, + test_data.h, + test_data_arc4.m, + test_data_arc4.n, + test_data_arc4.o, + test_data_arc4.p, + test_data_arc4.q, + test_data_arc4.r, + test_data_arc4.s, + test_data_arc4.t, + ) + const arc4_result = [...Array(asNumber(app_txn.numLogs)).keys()].fill(0).map((_, i) => app_txn.logs(i)) + + expect(arc4_result[0]).toEqual(avmLogs![0]) + expect(arc4_result[1]).toEqual(avmLogs![1]) + expect(arc4_result[1]).toEqual(arc4_result[2]) + expect(arc4_result[2]).toEqual(avmLogs![2]) + }) + }) +}) diff --git a/tests/artifacts/arc4-primitive-ops/contract.algo.ts b/tests/artifacts/arc4-primitive-ops/contract.algo.ts index 345a365..7e49aec 100644 --- a/tests/artifacts/arc4-primitive-ops/contract.algo.ts +++ b/tests/artifacts/arc4-primitive-ops/contract.algo.ts @@ -1,4 +1,4 @@ -import { arc4, BigUint, bytes } from '@algorandfoundation/algorand-typescript' +import { arc4, BigUint, bytes, emit } from '@algorandfoundation/algorand-typescript' import { Bool, Byte, Contract, interpretAsArc4, Str, UFixedNxM, UintN } from '@algorandfoundation/algorand-typescript/arc4' export class Arc4PrimitiveOpsContract extends Contract { @@ -344,4 +344,62 @@ export class Arc4PrimitiveOpsContract extends Contract { public verify_bool_from_log(a: bytes): Bool { return interpretAsArc4(a, 'log') } + + // TODO: recompile when puya-ts is updated + @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 { + const arc4_r = interpretAsArc4>(r) + const arc4_s = interpretAsArc4>(s) + const arc4_t = interpretAsArc4>(t) + + emit(new SwappedArc4({ m, n, o, p, q, r: arc4_r, s: arc4_s, t: arc4_t })) + emit('Swapped', a, b, c, d, e, f, g, h, m, n, o, p, q, arc4_r.copy(), arc4_s.copy(), arc4_t) + 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, + ) + } } + +class SwappedArc4 extends arc4.Struct<{ + m: arc4.UintN<64> + n: arc4.UintN<256> + o: arc4.UFixedNxM<32, 8> + p: arc4.UFixedNxM<256, 16> + q: arc4.Bool + r: arc4.StaticArray + s: arc4.DynamicArray + t: arc4.Tuple<[arc4.UintN32, arc4.UintN64, arc4.Str]> +}> {} diff --git a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal index b4b93f4..7711262 100644 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.approval.teal @@ -1,27 +1,26 @@ #pragma version 10 +#pragma typetrack false -tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.approvalProgram: +// @algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract.approvalProgram() -> uint64: +main: intcblock 1 8 64 0 bytecblock 0x151f7c75 0x00 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { - proto 0 1 txn NumAppArgs - bz __puya_arc4_router___bare_routing@58 - 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 // 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" + 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 __puya_arc4_router___verify_uintn_uintn_eq_route@2 __puya_arc4_router___verify_biguintn_uintn_eq_route@3 __puya_arc4_router___verify_uintn_biguintn_eq_route@4 __puya_arc4_router___verify_biguintn_biguintn_eq_route@5 __puya_arc4_router___verify_byte_byte_eq_route@6 __puya_arc4_router___verify_uintn_uintn_ne_route@7 __puya_arc4_router___verify_biguintn_uintn_ne_route@8 __puya_arc4_router___verify_uintn_biguintn_ne_route@9 __puya_arc4_router___verify_biguintn_biguintn_ne_route@10 __puya_arc4_router___verify_byte_byte_ne_route@11 __puya_arc4_router___verify_uintn_uintn_lt_route@12 __puya_arc4_router___verify_biguintn_uintn_lt_route@13 __puya_arc4_router___verify_uintn_biguintn_lt_route@14 __puya_arc4_router___verify_biguintn_biguintn_lt_route@15 __puya_arc4_router___verify_byte_byte_lt_route@16 __puya_arc4_router___verify_uintn_uintn_le_route@17 __puya_arc4_router___verify_biguintn_uintn_le_route@18 __puya_arc4_router___verify_uintn_biguintn_le_route@19 __puya_arc4_router___verify_biguintn_biguintn_le_route@20 __puya_arc4_router___verify_byte_byte_le_route@21 __puya_arc4_router___verify_uintn_uintn_gt_route@22 __puya_arc4_router___verify_biguintn_uintn_gt_route@23 __puya_arc4_router___verify_uintn_biguintn_gt_route@24 __puya_arc4_router___verify_biguintn_biguintn_gt_route@25 __puya_arc4_router___verify_byte_byte_gt_route@26 __puya_arc4_router___verify_uintn_uintn_ge_route@27 __puya_arc4_router___verify_biguintn_uintn_ge_route@28 __puya_arc4_router___verify_uintn_biguintn_ge_route@29 __puya_arc4_router___verify_biguintn_biguintn_ge_route@30 __puya_arc4_router___verify_byte_byte_ge_route@31 __puya_arc4_router___verify_uintn_init_route@32 __puya_arc4_router___verify_biguintn_init_route@33 __puya_arc4_router___verify_byte_init_route@34 __puya_arc4_router___verify_uintn_from_bytes_route@35 __puya_arc4_router___verify_biguintn_from_bytes_route@36 __puya_arc4_router___verify_byte_from_bytes_route@37 __puya_arc4_router___verify_uintn_from_log_route@38 __puya_arc4_router___verify_biguintn_from_log_route@39 __puya_arc4_router___verify_byte_from_log_route@40 __puya_arc4_router___verify_ufixednxm_bytes_route@41 __puya_arc4_router___verify_bigufixednxm_bytes_route@42 __puya_arc4_router___verify_ufixednxm_from_bytes_route@43 __puya_arc4_router___verify_bigufixednxm_from_bytes_route@44 __puya_arc4_router___verify_ufixednxm_from_log_route@45 __puya_arc4_router___verify_bigufixednxm_from_log_route@46 __puya_arc4_router___verify_string_init_route@47 __puya_arc4_router___verify_string_add_route@48 __puya_arc4_router___verify_string_eq_route@49 __puya_arc4_router___verify_string_bytes_route@50 __puya_arc4_router___verify_string_from_bytes_route@51 __puya_arc4_router___verify_string_from_log_route@52 __puya_arc4_router___verify_bool_bytes_route@53 __puya_arc4_router___verify_bool_from_bytes_route@54 __puya_arc4_router___verify_bool_from_log_route@55 + 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 - retsub + return -__puya_arc4_router___verify_uintn_uintn_eq_route@2: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:5 +main_verify_emit_route@57: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:349 // @arc4.abimethod() txn OnCompletion ! @@ -31,25 +30,67 @@ __puya_arc4_router___verify_uintn_uintn_eq_route@2: // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 - extract 2 0 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 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:5 + 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_uintn_uintn_eq - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + 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 - retsub + return -__puya_arc4_router___verify_biguintn_uintn_eq_route@3: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:13 +main_verify_bool_from_bytes_route@55: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:339 // @arc4.abimethod() txn OnCompletion ! @@ -60,24 +101,17 @@ __puya_arc4_router___verify_biguintn_uintn_eq_route@3: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:339 // @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 - retsub + return -__puya_arc4_router___verify_uintn_biguintn_eq_route@4: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:21 +main_verify_bool_bytes_route@54: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:335 // @arc4.abimethod() txn OnCompletion ! @@ -87,25 +121,23 @@ __puya_arc4_router___verify_uintn_biguintn_eq_route@4: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:335 // @arc4.abimethod() - callsub verify_uintn_biguintn_eq - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + dup + len + itob + extract 6 2 + swap + concat bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_biguintn_eq_route@5: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:29 +main_verify_string_from_log_route@53: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:331 // @arc4.abimethod() txn OnCompletion ! @@ -116,24 +148,18 @@ __puya_arc4_router___verify_biguintn_biguintn_eq_route@5: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:331 // @arc4.abimethod() - callsub verify_biguintn_biguintn_eq - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_string_from_log bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_byte_byte_eq_route@6: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:37 +main_verify_string_from_bytes_route@52: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:327 // @arc4.abimethod() txn OnCompletion ! @@ -144,24 +170,17 @@ __puya_arc4_router___verify_byte_byte_eq_route@6: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:327 // @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 - retsub + return -__puya_arc4_router___verify_uintn_uintn_ne_route@7: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:45 +main_verify_string_bytes_route@51: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:322 // @arc4.abimethod() txn OnCompletion ! @@ -172,24 +191,24 @@ __puya_arc4_router___verify_uintn_uintn_ne_route@7: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:322 // @arc4.abimethod() - callsub verify_uintn_uintn_ne - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_string_bytes + dup + len + itob + extract 6 2 + swap + concat bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_uintn_ne_route@8: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:53 +main_verify_string_eq_route@50: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:318 // @arc4.abimethod() txn OnCompletion ! @@ -199,12 +218,10 @@ __puya_arc4_router___verify_biguintn_uintn_ne_route@8: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:318 // @arc4.abimethod() - callsub verify_biguintn_uintn_ne + callsub verify_string_eq bytec_1 // 0x00 intc_3 // 0 uncover 2 @@ -214,10 +231,10 @@ __puya_arc4_router___verify_biguintn_uintn_ne_route@8: concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_uintn_biguintn_ne_route@9: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:61 +main_verify_string_add_route@49: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:313 // @arc4.abimethod() txn OnCompletion ! @@ -227,25 +244,19 @@ __puya_arc4_router___verify_uintn_biguintn_ne_route@9: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:313 // @arc4.abimethod() - callsub verify_uintn_biguintn_ne - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_string_add bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_biguintn_ne_route@10: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:69 +main_verify_string_init_route@48: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:308 // @arc4.abimethod() txn OnCompletion ! @@ -256,24 +267,18 @@ __puya_arc4_router___verify_biguintn_biguintn_ne_route@10: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:308 // @arc4.abimethod() - callsub verify_biguintn_biguintn_ne - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_string_init bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_byte_byte_ne_route@11: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:77 +main_verify_bigufixednxm_from_log_route@47: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:304 // @arc4.abimethod() txn OnCompletion ! @@ -284,24 +289,18 @@ __puya_arc4_router___verify_byte_byte_ne_route@11: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:304 // @arc4.abimethod() - callsub verify_byte_byte_ne - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_bigufixednxm_from_log bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_uintn_uintn_lt_route@12: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:85 +main_verify_ufixednxm_from_log_route@46: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:300 // @arc4.abimethod() txn OnCompletion ! @@ -312,24 +311,18 @@ __puya_arc4_router___verify_uintn_uintn_lt_route@12: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:300 // @arc4.abimethod() - callsub verify_uintn_uintn_lt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_ufixednxm_from_log bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_uintn_lt_route@13: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:93 +main_verify_bigufixednxm_from_bytes_route@45: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:296 // @arc4.abimethod() txn OnCompletion ! @@ -340,24 +333,17 @@ __puya_arc4_router___verify_biguintn_uintn_lt_route@13: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:296 // @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 - retsub + return -__puya_arc4_router___verify_uintn_biguintn_lt_route@14: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:101 +main_verify_ufixednxm_from_bytes_route@44: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:292 // @arc4.abimethod() txn OnCompletion ! @@ -368,24 +354,17 @@ __puya_arc4_router___verify_uintn_biguintn_lt_route@14: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:292 // @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 - retsub + return -__puya_arc4_router___verify_biguintn_biguintn_lt_route@15: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:109 +main_verify_bigufixednxm_bytes_route@43: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:288 // @arc4.abimethod() txn OnCompletion ! @@ -395,25 +374,23 @@ __puya_arc4_router___verify_biguintn_biguintn_lt_route@15: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:288 // @arc4.abimethod() - callsub verify_biguintn_biguintn_lt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + dup + len + itob + extract 6 2 + swap + concat bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_byte_byte_lt_route@16: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:117 +main_verify_ufixednxm_bytes_route@42: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:284 // @arc4.abimethod() txn OnCompletion ! @@ -423,25 +400,23 @@ __puya_arc4_router___verify_byte_byte_lt_route@16: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:284 // @arc4.abimethod() - callsub verify_byte_byte_lt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + dup + len + itob + extract 6 2 + swap + concat bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_uintn_uintn_le_route@17: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:125 +main_verify_byte_from_log_route@41: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:280 // @arc4.abimethod() txn OnCompletion ! @@ -452,24 +427,18 @@ __puya_arc4_router___verify_uintn_uintn_le_route@17: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:280 // @arc4.abimethod() - callsub verify_uintn_uintn_le - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_byte_from_log bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_uintn_le_route@18: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:133 +main_verify_biguintn_from_log_route@40: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:276 // @arc4.abimethod() txn OnCompletion ! @@ -480,24 +449,18 @@ __puya_arc4_router___verify_biguintn_uintn_le_route@18: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:276 // @arc4.abimethod() - callsub verify_biguintn_uintn_le - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_biguintn_from_log bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_uintn_biguintn_le_route@19: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:141 +main_verify_uintn_from_log_route@39: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:272 // @arc4.abimethod() txn OnCompletion ! @@ -508,24 +471,18 @@ __puya_arc4_router___verify_uintn_biguintn_le_route@19: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:272 // @arc4.abimethod() - callsub verify_uintn_biguintn_le - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_uintn_from_log bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_biguintn_le_route@20: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:149 +main_verify_byte_from_bytes_route@38: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:268 // @arc4.abimethod() txn OnCompletion ! @@ -536,24 +493,17 @@ __puya_arc4_router___verify_biguintn_biguintn_le_route@20: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:268 // @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 - retsub + return -__puya_arc4_router___verify_byte_byte_le_route@21: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:157 +main_verify_biguintn_from_bytes_route@37: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:264 // @arc4.abimethod() txn OnCompletion ! @@ -564,24 +514,17 @@ __puya_arc4_router___verify_byte_byte_le_route@21: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:264 // @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 - retsub + return -__puya_arc4_router___verify_uintn_uintn_gt_route@22: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:165 +main_verify_uintn_from_bytes_route@36: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:260 // @arc4.abimethod() txn OnCompletion ! @@ -592,24 +535,17 @@ __puya_arc4_router___verify_uintn_uintn_gt_route@22: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:260 // @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 - retsub + return -__puya_arc4_router___verify_biguintn_uintn_gt_route@23: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:173 +main_verify_byte_init_route@35: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:255 // @arc4.abimethod() txn OnCompletion ! @@ -620,24 +556,18 @@ __puya_arc4_router___verify_biguintn_uintn_gt_route@23: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:255 // @arc4.abimethod() - callsub verify_biguintn_uintn_gt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_byte_init bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_uintn_biguintn_gt_route@24: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:181 +main_verify_biguintn_init_route@34: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:250 // @arc4.abimethod() txn OnCompletion ! @@ -648,24 +578,18 @@ __puya_arc4_router___verify_uintn_biguintn_gt_route@24: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:250 // @arc4.abimethod() - callsub verify_uintn_biguintn_gt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_biguintn_init bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_biguintn_gt_route@25: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:189 +main_verify_uintn_init_route@33: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:245 // @arc4.abimethod() txn OnCompletion ! @@ -676,24 +600,18 @@ __puya_arc4_router___verify_biguintn_biguintn_gt_route@25: // 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 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:245 // @arc4.abimethod() - callsub verify_biguintn_biguintn_gt - bytec_1 // 0x00 - intc_3 // 0 - uncover 2 - setbit + callsub verify_uintn_init bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_byte_byte_gt_route@26: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:197 +main_verify_byte_byte_ge_route@32: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:237 // @arc4.abimethod() txn OnCompletion ! @@ -706,9 +624,9 @@ __puya_arc4_router___verify_byte_byte_gt_route@26: extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:197 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:237 // @arc4.abimethod() - callsub verify_byte_byte_gt + callsub verify_byte_byte_ge bytec_1 // 0x00 intc_3 // 0 uncover 2 @@ -718,10 +636,10 @@ __puya_arc4_router___verify_byte_byte_gt_route@26: concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_uintn_uintn_ge_route@27: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:205 +main_verify_biguintn_biguintn_ge_route@31: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:229 // @arc4.abimethod() txn OnCompletion ! @@ -734,9 +652,9 @@ __puya_arc4_router___verify_uintn_uintn_ge_route@27: extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:205 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:229 // @arc4.abimethod() - callsub verify_uintn_uintn_ge + callsub verify_biguintn_biguintn_ge bytec_1 // 0x00 intc_3 // 0 uncover 2 @@ -746,10 +664,10 @@ __puya_arc4_router___verify_uintn_uintn_ge_route@27: concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_uintn_ge_route@28: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:213 +main_verify_uintn_biguintn_ge_route@30: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:221 // @arc4.abimethod() txn OnCompletion ! @@ -762,9 +680,9 @@ __puya_arc4_router___verify_biguintn_uintn_ge_route@28: extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:213 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:221 // @arc4.abimethod() - callsub verify_biguintn_uintn_ge + callsub verify_uintn_biguintn_ge bytec_1 // 0x00 intc_3 // 0 uncover 2 @@ -774,10 +692,10 @@ __puya_arc4_router___verify_biguintn_uintn_ge_route@28: concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_uintn_biguintn_ge_route@29: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:221 +main_verify_biguintn_uintn_ge_route@29: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:213 // @arc4.abimethod() txn OnCompletion ! @@ -790,9 +708,9 @@ __puya_arc4_router___verify_uintn_biguintn_ge_route@29: extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:221 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:213 // @arc4.abimethod() - callsub verify_uintn_biguintn_ge + callsub verify_biguintn_uintn_ge bytec_1 // 0x00 intc_3 // 0 uncover 2 @@ -802,10 +720,10 @@ __puya_arc4_router___verify_uintn_biguintn_ge_route@29: concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_biguintn_ge_route@30: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:229 +main_verify_uintn_uintn_ge_route@28: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:205 // @arc4.abimethod() txn OnCompletion ! @@ -818,9 +736,9 @@ __puya_arc4_router___verify_biguintn_biguintn_ge_route@30: extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:229 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:205 // @arc4.abimethod() - callsub verify_biguintn_biguintn_ge + callsub verify_uintn_uintn_ge bytec_1 // 0x00 intc_3 // 0 uncover 2 @@ -830,10 +748,10 @@ __puya_arc4_router___verify_biguintn_biguintn_ge_route@30: concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_byte_byte_ge_route@31: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:237 +main_verify_byte_byte_gt_route@27: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:197 // @arc4.abimethod() txn OnCompletion ! @@ -846,9 +764,9 @@ __puya_arc4_router___verify_byte_byte_ge_route@31: extract 2 0 txna ApplicationArgs 2 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:237 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:197 // @arc4.abimethod() - callsub verify_byte_byte_ge + callsub verify_byte_byte_gt bytec_1 // 0x00 intc_3 // 0 uncover 2 @@ -858,10 +776,10 @@ __puya_arc4_router___verify_byte_byte_ge_route@31: concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_uintn_init_route@32: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:245 +main_verify_biguintn_biguintn_gt_route@26: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:189 // @arc4.abimethod() txn OnCompletion ! @@ -872,18 +790,24 @@ __puya_arc4_router___verify_uintn_init_route@32: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:245 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:189 // @arc4.abimethod() - callsub verify_uintn_init + callsub verify_biguintn_biguintn_gt + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_init_route@33: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:250 +main_verify_uintn_biguintn_gt_route@25: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:181 // @arc4.abimethod() txn OnCompletion ! @@ -894,18 +818,24 @@ __puya_arc4_router___verify_biguintn_init_route@33: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:250 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:181 // @arc4.abimethod() - callsub verify_biguintn_init + callsub verify_uintn_biguintn_gt + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_byte_init_route@34: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:255 +main_verify_biguintn_uintn_gt_route@24: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:173 // @arc4.abimethod() txn OnCompletion ! @@ -916,18 +846,24 @@ __puya_arc4_router___verify_byte_init_route@34: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:255 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:173 // @arc4.abimethod() - callsub verify_byte_init + callsub verify_biguintn_uintn_gt + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_uintn_from_bytes_route@35: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:260 +main_verify_uintn_uintn_gt_route@23: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:165 // @arc4.abimethod() txn OnCompletion ! @@ -938,18 +874,24 @@ __puya_arc4_router___verify_uintn_from_bytes_route@35: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:260 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:165 // @arc4.abimethod() - callsub verify_uintn_from_bytes + callsub verify_uintn_uintn_gt + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_from_bytes_route@36: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:264 +main_verify_byte_byte_le_route@22: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:157 // @arc4.abimethod() txn OnCompletion ! @@ -960,18 +902,24 @@ __puya_arc4_router___verify_biguintn_from_bytes_route@36: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:264 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:157 // @arc4.abimethod() - callsub verify_biguintn_from_bytes + callsub verify_byte_byte_le + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_byte_from_bytes_route@37: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:268 +main_verify_biguintn_biguintn_le_route@21: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:149 // @arc4.abimethod() txn OnCompletion ! @@ -982,18 +930,24 @@ __puya_arc4_router___verify_byte_from_bytes_route@37: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:268 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:149 // @arc4.abimethod() - callsub verify_byte_from_bytes + callsub verify_biguintn_biguintn_le + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_uintn_from_log_route@38: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:272 +main_verify_uintn_biguintn_le_route@20: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:141 // @arc4.abimethod() txn OnCompletion ! @@ -1004,18 +958,24 @@ __puya_arc4_router___verify_uintn_from_log_route@38: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:272 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:141 // @arc4.abimethod() - callsub verify_uintn_from_log + callsub verify_uintn_biguintn_le + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_biguintn_from_log_route@39: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:276 +main_verify_biguintn_uintn_le_route@19: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:133 // @arc4.abimethod() txn OnCompletion ! @@ -1026,18 +986,24 @@ __puya_arc4_router___verify_biguintn_from_log_route@39: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:276 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:133 // @arc4.abimethod() - callsub verify_biguintn_from_log + callsub verify_biguintn_uintn_le + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_byte_from_log_route@40: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:280 +main_verify_uintn_uintn_le_route@18: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:125 // @arc4.abimethod() txn OnCompletion ! @@ -1048,18 +1014,24 @@ __puya_arc4_router___verify_byte_from_log_route@40: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:280 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:125 // @arc4.abimethod() - callsub verify_byte_from_log + callsub verify_uintn_uintn_le + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_ufixednxm_bytes_route@41: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:284 +main_verify_byte_byte_lt_route@17: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:117 // @arc4.abimethod() txn OnCompletion ! @@ -1069,24 +1041,25 @@ __puya_arc4_router___verify_ufixednxm_bytes_route@41: // 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 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:117 // @arc4.abimethod() - callsub verify_ufixednxm_bytes - dup - len - itob - extract 6 2 - swap - concat + callsub verify_byte_byte_lt + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_bigufixednxm_bytes_route@42: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:288 +main_verify_biguintn_biguintn_lt_route@16: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:109 // @arc4.abimethod() txn OnCompletion ! @@ -1096,24 +1069,25 @@ __puya_arc4_router___verify_bigufixednxm_bytes_route@42: // 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 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:109 // @arc4.abimethod() - callsub verify_bigufixednxm_bytes - dup - len - itob - extract 6 2 - swap - concat + callsub verify_biguintn_biguintn_lt + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_ufixednxm_from_bytes_route@43: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:292 +main_verify_uintn_biguintn_lt_route@15: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:101 // @arc4.abimethod() txn OnCompletion ! @@ -1124,18 +1098,24 @@ __puya_arc4_router___verify_ufixednxm_from_bytes_route@43: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:292 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:101 // @arc4.abimethod() - callsub verify_ufixednxm_from_bytes + callsub verify_uintn_biguintn_lt + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_bigufixednxm_from_bytes_route@44: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:296 +main_verify_biguintn_uintn_lt_route@14: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:93 // @arc4.abimethod() txn OnCompletion ! @@ -1146,18 +1126,24 @@ __puya_arc4_router___verify_bigufixednxm_from_bytes_route@44: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:296 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:93 // @arc4.abimethod() - callsub verify_bigufixednxm_from_bytes + callsub verify_biguintn_uintn_lt + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_ufixednxm_from_log_route@45: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:300 +main_verify_uintn_uintn_lt_route@13: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:85 // @arc4.abimethod() txn OnCompletion ! @@ -1168,18 +1154,24 @@ __puya_arc4_router___verify_ufixednxm_from_log_route@45: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:300 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:85 // @arc4.abimethod() - callsub verify_ufixednxm_from_log + callsub verify_uintn_uintn_lt + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_bigufixednxm_from_log_route@46: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:304 +main_verify_byte_byte_ne_route@12: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:77 // @arc4.abimethod() txn OnCompletion ! @@ -1190,18 +1182,24 @@ __puya_arc4_router___verify_bigufixednxm_from_log_route@46: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:304 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:77 // @arc4.abimethod() - callsub verify_bigufixednxm_from_log + callsub verify_byte_byte_ne + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_string_init_route@47: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:308 +main_verify_biguintn_biguintn_ne_route@11: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:69 // @arc4.abimethod() txn OnCompletion ! @@ -1212,18 +1210,24 @@ __puya_arc4_router___verify_string_init_route@47: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:308 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:69 // @arc4.abimethod() - callsub verify_string_init + callsub verify_biguintn_biguintn_ne + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_string_add_route@48: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:313 +main_verify_uintn_biguintn_ne_route@10: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:61 // @arc4.abimethod() txn OnCompletion ! @@ -1233,19 +1237,25 @@ __puya_arc4_router___verify_string_add_route@48: // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 + extract 2 0 txna ApplicationArgs 2 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:313 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:61 // @arc4.abimethod() - callsub verify_string_add + callsub verify_uintn_biguintn_ne + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_string_eq_route@49: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:318 +main_verify_biguintn_uintn_ne_route@9: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:53 // @arc4.abimethod() txn OnCompletion ! @@ -1255,10 +1265,12 @@ __puya_arc4_router___verify_string_eq_route@49: // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 + extract 2 0 txna ApplicationArgs 2 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:318 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:53 // @arc4.abimethod() - callsub verify_string_eq + callsub verify_biguintn_uintn_ne bytec_1 // 0x00 intc_3 // 0 uncover 2 @@ -1268,10 +1280,10 @@ __puya_arc4_router___verify_string_eq_route@49: concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_string_bytes_route@50: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:322 +main_verify_uintn_uintn_ne_route@8: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:45 // @arc4.abimethod() txn OnCompletion ! @@ -1282,24 +1294,24 @@ __puya_arc4_router___verify_string_bytes_route@50: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:322 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:45 // @arc4.abimethod() - callsub verify_string_bytes - dup - len - itob - extract 6 2 - swap - concat + callsub verify_uintn_uintn_ne + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_string_from_bytes_route@51: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:327 +main_verify_byte_byte_eq_route@7: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:37 // @arc4.abimethod() txn OnCompletion ! @@ -1310,18 +1322,24 @@ __puya_arc4_router___verify_string_from_bytes_route@51: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:327 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:37 // @arc4.abimethod() - callsub verify_string_from_bytes + callsub verify_byte_byte_eq + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_string_from_log_route@52: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:331 +main_verify_biguintn_biguintn_eq_route@6: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:29 // @arc4.abimethod() txn OnCompletion ! @@ -1332,18 +1350,24 @@ __puya_arc4_router___verify_string_from_log_route@52: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:331 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:29 // @arc4.abimethod() - callsub verify_string_from_log + callsub verify_biguintn_biguintn_eq + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_bool_bytes_route@53: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:335 +main_verify_uintn_biguintn_eq_route@5: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:21 // @arc4.abimethod() txn OnCompletion ! @@ -1353,24 +1377,25 @@ __puya_arc4_router___verify_bool_bytes_route@53: // 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 + extract 2 0 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:21 // @arc4.abimethod() - callsub verify_bool_bytes - dup - len - itob - extract 6 2 - swap - concat + callsub verify_uintn_biguintn_eq + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_bool_from_bytes_route@54: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:339 +main_verify_biguintn_uintn_eq_route@4: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:13 // @arc4.abimethod() txn OnCompletion ! @@ -1381,18 +1406,24 @@ __puya_arc4_router___verify_bool_from_bytes_route@54: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:339 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:13 // @arc4.abimethod() - callsub verify_bool_from_bytes + callsub verify_biguintn_uintn_eq + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_bool_from_log_route@55: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:343 +main_verify_uintn_uintn_eq_route@3: + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:5 // @arc4.abimethod() txn OnCompletion ! @@ -1403,32 +1434,32 @@ __puya_arc4_router___verify_bool_from_log_route@55: // export class Arc4PrimitiveOpsContract extends Contract { txna ApplicationArgs 1 extract 2 0 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:343 + txna ApplicationArgs 2 + extract 2 0 + // tests/artifacts/arc4-primitive-ops/contract.algo.ts:5 // @arc4.abimethod() - callsub verify_bool_from_log + callsub verify_uintn_uintn_eq + bytec_1 // 0x00 + intc_3 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___bare_routing@58: +main_bare_routing@60: // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 // export class Arc4PrimitiveOpsContract extends Contract { txn OnCompletion - bnz __puya_arc4_router___after_if_else@62 + bnz main_after_if_else@64 txn ApplicationID ! assert // can only call when creating intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@62: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:4 - // export class Arc4PrimitiveOpsContract extends Contract { - intc_3 // 0 - retsub + return // tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_uintn_eq(a: bytes, b: bytes) -> uint64: @@ -2565,42 +2596,6 @@ verify_byte_init: retsub -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_uintn_from_bytes(a: bytes) -> bytes: -verify_uintn_from_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:260-261 - // @arc4.abimethod() - // public verify_uintn_from_bytes(a: bytes): UintN<32> { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:262 - // return interpretAsArc4>(a) - frame_dig -1 - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_biguintn_from_bytes(a: bytes) -> bytes: -verify_biguintn_from_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:264-265 - // @arc4.abimethod() - // public verify_biguintn_from_bytes(a: bytes): UintN<256> { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:266 - // return interpretAsArc4>(a) - frame_dig -1 - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_byte_from_bytes(a: bytes) -> bytes: -verify_byte_from_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:268-269 - // @arc4.abimethod() - // public verify_byte_from_bytes(a: bytes): Byte { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:270 - // return interpretAsArc4(a) - frame_dig -1 - 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 @@ -2655,54 +2650,6 @@ verify_byte_from_log: retsub -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_ufixednxm_bytes(a: bytes) -> bytes: -verify_ufixednxm_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:284-285 - // @arc4.abimethod() - // public verify_ufixednxm_bytes(a: UFixedNxM<32, 8>): bytes { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:286 - // return a.bytes - frame_dig -1 - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_bigufixednxm_bytes(a: bytes) -> bytes: -verify_bigufixednxm_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:288-289 - // @arc4.abimethod() - // public verify_bigufixednxm_bytes(a: UFixedNxM<256, 16>): bytes { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:290 - // return a.bytes - frame_dig -1 - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_ufixednxm_from_bytes(a: bytes) -> bytes: -verify_ufixednxm_from_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:292-293 - // @arc4.abimethod() - // public verify_ufixednxm_from_bytes(a: bytes): UFixedNxM<32, 8> { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:294 - // return interpretAsArc4>(a) - frame_dig -1 - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_bigufixednxm_from_bytes(a: bytes) -> bytes: -verify_bigufixednxm_from_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:296-297 - // @arc4.abimethod() - // public verify_bigufixednxm_from_bytes(a: bytes): UFixedNxM<256, 16> { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:298 - // return interpretAsArc4>(a) - frame_dig -1 - 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 @@ -2818,18 +2765,6 @@ verify_string_bytes: retsub -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_string_from_bytes(a: bytes) -> bytes: -verify_string_from_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:327-328 - // @arc4.abimethod() - // public verify_string_from_bytes(a: bytes): Str { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:329 - // return interpretAsArc4(a) - frame_dig -1 - 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 @@ -2848,30 +2783,6 @@ verify_string_from_log: retsub -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_bool_bytes(a: bytes) -> bytes: -verify_bool_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:335-336 - // @arc4.abimethod() - // public verify_bool_bytes(a: Bool): bytes { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:337 - // return a.bytes - frame_dig -1 - retsub - - -// tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.verify_bool_from_bytes(a: bytes) -> bytes: -verify_bool_from_bytes: - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:339-340 - // @arc4.abimethod() - // public verify_bool_from_bytes(a: bytes): Bool { - proto 1 1 - // tests/artifacts/arc4-primitive-ops/contract.algo.ts:341 - // return interpretAsArc4(a) - frame_dig -1 - 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 @@ -2888,3 +2799,167 @@ verify_bool_from_log: == 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 index 7d20805..5da0118 100644 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json @@ -1,1137 +1,1215 @@ { - "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" - } - } + "hints": { + "verify_uintn_uintn_eq(byte[],byte[])bool": { + "call_config": { + "no_op": "CALL" + } }, - "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSA4IDY0IDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NSAweDAwCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OAogICAgcHVzaGJ5dGVzcyAweDk2ZjE0MTE2IDB4ZWQ2NjYwOTYgMHgyY2EwMzUyYiAweDg1OTA3ZDQwIDB4NGViMmFmNGEgMHgyY2JlYzQ1YiAweDA3NjY2ZmQ5IDB4MzcwYmFiZDMgMHgyYjZiM2VmMCAweDI3ZTIxYTk4IDB4MzM5ZGE5N2MgMHg3ODk4ZWQ5NyAweDFmMTMwY2VjIDB4Yzc0ODY2NGUgMHhhMmJhYzE0YiAweDdhNDYwY2IxIDB4ZGNhYjFmMDEgMHg5N2Q5MDY0ZCAweGNlMDZjMmEwIDB4N2MxMWUzNzUgMHhkY2RiY2VlMCAweDc3YTRiNjhkIDB4NGY1NDA2MjYgMHgwOTVhZWQ0MSAweGRmNzhjZGM2IDB4ZTNiN2U5MTggMHg1NTMzNzAwOCAweDliYjFjZDY2IDB4ODE0ODRkOWQgMHg3OWU5Y2IwMyAweDlhMDNkZjEwIDB4ZDNmMGU0NGIgMHg2NzNkYjJiZCAweDk4MmRiMjMzIDB4YWZmYmRmMGUgMHg4ZTRhMzBmNyAweDI4OGFmNzZlIDB4OGJkODRhMDQgMHhmY2Q1NWUxZiAweDBmMTU3NGZlIDB4YjJjYjEzYmUgMHhkMDU5ZWVhNyAweDRjYzRjMTU3IDB4M2QxN2FjNmUgMHhmN2YzZDVmYyAweGY4YzhmOGQ1IDB4NDNmNzE2MmEgMHg0MmUwOTA3NSAweGQ5NTZmNTc1IDB4NmMwMTYwZGYgMHhhODkwMTUwYiAweDBiMmY0YzNmIDB4OWRiOWQzMjcgMHhlNGQ5NTBhMSAvLyBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfZXEoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9sdChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfbGUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2d0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9nZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9pbml0KGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9pbml0KGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9pbml0KGJ5dGVbXSlieXRlIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDMyIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhieXRlW10pYnl0ZSIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9sb2coYnl0ZVtdKWJ5dGUiLCBtZXRob2QgInZlcmlmeV91Zml4ZWRueG1fYnl0ZXModWZpeGVkMzJ4OClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXModWZpeGVkMjU2eDE2KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGJ5dGVbXSl1Zml4ZWQzMng4IiwgbWV0aG9kICJ2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMoYnl0ZVtdKXVmaXhlZDI1NngxNiIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMzJ4OCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMjU2eDE2IiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2luaXQoc3RyaW5nKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19hZGQoc3RyaW5nLHN0cmluZylzdHJpbmciLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZXEoc3RyaW5nLHN0cmluZylib29sIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2J5dGVzKHN0cmluZylieXRlW10iLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhieXRlW10pc3RyaW5nIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nKGJ5dGVbXSlzdHJpbmciLCBtZXRob2QgInZlcmlmeV9ib29sX2J5dGVzKGJvb2wpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2xvZyhieXRlW10pYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9lcV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbmVfcm91dGVANyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbmVfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbmVfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbHRfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbGVfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbGVfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ2Vfcm91dGVAMjcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAyOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2Vfcm91dGVAMzAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5faW5pdF9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9pbml0X3JvdXRlQDM0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZ19yb3V0ZUAzOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2xvZ19yb3V0ZUA0MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXNfcm91dGVANDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlc19yb3V0ZUA0NCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfYWRkX3JvdXRlQDQ4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19ieXRlc19yb3V0ZUA1MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9ieXRlc19yb3V0ZUA1MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZXFfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZXFfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9uZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sdF9yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbHRfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0X3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfbHRfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sZV9yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbGVfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlX3JvdXRlQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9ieXRlX2xlX3JvdXRlQDIxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fYmlndWludG5fZ3QKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9ieXRlX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9nZV9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ2Vfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlX3JvdXRlQDMwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZ2Vfcm91dGVAMzE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9pbml0X3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2luaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9pbml0X3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2luaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2luaXRfcm91dGVAMzQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzX3JvdXRlQDM3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fZnJvbV9sb2dfcm91dGVAMzk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fbG9nX3JvdXRlQDQwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fYnl0ZXNfcm91dGVANDE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91Zml4ZWRueG1fYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2FkZF9yb3V0ZUA0ODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19hZGQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlc19yb3V0ZUA1MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2J5dGVzX3JvdXRlQDUzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYm9vbF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fYnl0ZXNfcm91dGVANTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2xvZ19yb3V0ZUA1NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgaW50Y18zIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUtNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExCiAgICAvLyByZXR1cm4gYVVpbnROID09PSBiVWludE4KICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMy0xNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEtMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gcmV0dXJuIGFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIHJldHVybiBhVWludE4gPT09IGJVaW50TgogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzctMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzCiAgICAvLyByZXR1cm4gYUJ5dGUgPT09IGJCeXRlCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDUtNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIHJldHVybiBhVWludE4gIT09IGJVaW50TgogICAgIT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUzLTU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkKICAgIC8vIHJldHVybiAhYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEtNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NwogICAgLy8gcmV0dXJuICFhVWludE4uYnl0ZXMuZXF1YWxzKGJVaW50Ti5ieXRlcykKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyByZXR1cm4gYVVpbnROICE9PSBiVWludE4KICAgICE9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gcmV0dXJuIGFCeXRlICE9PSBiQnl0ZQogICAgIT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1LTg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzLTk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgQmlnVWludChiVWludE4ubmF0aXZlKQogICAgYnRvaQogICAgaXRvYgogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMS0xMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNwogICAgLy8gcmV0dXJuIEJpZ1VpbnQoYVVpbnROLm5hdGl2ZSkgPCBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA5LTExMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE1CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8IGJVaW50Ti5uYXRpdmUKICAgIGI8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNy0xMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlIDwgYkJ5dGUubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUtMTI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzLTEzNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzOAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM5CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8PSBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MS0xNDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NwogICAgLy8gcmV0dXJuIEJpZ1VpbnQoYVVpbnROLm5hdGl2ZSkgPD0gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgaXRvYgogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDktMTUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IGJVaW50Ti5uYXRpdmUKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTctMTU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MwogICAgLy8gcmV0dXJuIGFCeXRlLm5hdGl2ZSA8PSBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUtMTY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3My0xNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPiBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxLTE4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA+IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODktMTkwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID4gYlVpbnROLm5hdGl2ZQogICAgYj4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3LTE5OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPiBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNS0yMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID49IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTMtMjE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID49IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxLTIyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA+PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOS0yMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gYlVpbnROLm5hdGl2ZQogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNy0yMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlID49IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9pbml0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VpbnRuX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ1LTI0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5faW5pdChhOiBieXRlcyk6IFVpbnROPDMyPiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDgKICAgIC8vIHJldHVybiBuZXcgVWludE48MzI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIHB1c2hpbnQgNCAvLyA0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBwdXNoaW50IDQgLy8gNAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9pbml0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRuX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwLTI1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5faW5pdChhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUzCiAgICAvLyByZXR1cm4gbmV3IFVpbnROPDI1Nj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgcHVzaGludCAzMiAvLyAzMgogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgcHVzaGludCAzMiAvLyAzMgogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9pbml0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1NS0yNTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfaW5pdChhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU4CiAgICAvLyByZXR1cm4gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5fZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAtMjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MgogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVaW50TjwzMj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0LTI2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFVpbnROPDI1Nj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OC0yNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcwCiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PEJ5dGU+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91aW50bl9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzItMjczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9mcm9tX2xvZyhhOiBieXRlcyk6IFVpbnROPDMyPiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzQKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VWludE48MzI+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2LTI3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fZnJvbV9sb2coYTogYnl0ZXMpOiBVaW50TjwyNTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3OAogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVaW50TjwyNTY+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MC0yODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9sb2coYTogYnl0ZXMpOiBCeXRlIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MgogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxCeXRlPihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWZpeGVkbnhtX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQtMjg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91Zml4ZWRueG1fYnl0ZXMoYTogVUZpeGVkTnhNPDMyLCA4Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NgogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4LTI4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzKGE6IFVGaXhlZE54TTwyNTYsIDE2Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MAogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Mi0yOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDMyLCA4PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTQKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VUZpeGVkTnhNPDMyLCA4Pj4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Ni0yOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDI1NiwgMTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5OAogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVRml4ZWROeE08MjU2LCAxNj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMC0zMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwzMiwgOD4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAyCiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFVGaXhlZE54TTwzMiwgOD4+KGEsICdsb2cnKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEJ5dGVzIGhhcyB2YWxpZCBwcmVmaXgKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNC0zMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwyNTYsIDE2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDYKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VUZpeGVkTnhNPDI1NiwgMTY+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA4LTMwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2luaXQoYTogc3RyaW5nKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihgSGVsbG8sICR7YX1gKQogICAgcHVzaGJ5dGVzICJIZWxsbywgIgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMtMzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfYWRkKGE6IFN0ciwgYjogU3RyKTogU3RyIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5uYXRpdmUuY29uY2F0KGIubmF0aXZlKQogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE2CiAgICAvLyByZXR1cm4gbmV3IFN0cihyZXN1bHQpCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3N0cmluZ19lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgtMzE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZXEoYTogU3RyLCBiOiBTdHIpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMAogICAgLy8gcmV0dXJuIGEgPT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIyLTMyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2J5dGVzKGE6IHN0cmluZyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNQogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNy0zMjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzKGE6IGJ5dGVzKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyOQogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxTdHI+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMS0zMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2xvZyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzMKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8U3RyPihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNS0zMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfYnl0ZXMoYTogQm9vbCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNwogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5LTM0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qm9vbD4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYm9vbF9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMtMzQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ib29sX2Zyb21fbG9nKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDUKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qm9vbD4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" + "verify_biguintn_uintn_eq(byte[],byte[])bool": { + "call_config": { + "no_op": "CALL" + } }, - "state": { - "global": { - "num_byte_slices": 0, - "num_uints": 0 - }, - "local": { - "num_byte_slices": 0, - "num_uints": 0 - } + "verify_uintn_biguintn_eq(byte[],byte[])bool": { + "call_config": { + "no_op": "CALL" + } }, - "schema": { - "global": { - "declared": {}, - "reserved": {} - }, - "local": { - "declared": {}, - "reserved": {} - } + "verify_biguintn_biguintn_eq(byte[],byte[])bool": { + "call_config": { + "no_op": "CALL" + } }, - "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" - } - } - ], - "networks": {} + "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" + } }, - "bare_call_config": { - "no_op": "CREATE" + "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" + } } -} \ No newline at end of file + }, + "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 index ff6a4bf..392c060 100644 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc56.json +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc56.json @@ -1263,6 +1263,263 @@ "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": [ @@ -1303,205 +1560,207 @@ "sourceInfo": [ { "pc": [ - 2956, - 2973, - 2990, - 3031, - 3048, - 3141, - 3170 + 2992, + 3009, + 3026, + 3043, + 3060, + 3147, + 3164 ], "errorMessage": "Bytes has valid prefix" }, { "pc": [ 418, - 451, - 484, - 517, - 550, - 583, - 616, - 649, - 682, - 715, - 748, - 781, - 814, - 847, - 880, - 913, - 946, - 979, - 1012, - 1045, - 1078, - 1111, - 1144, - 1177, - 1210, - 1243, - 1276, - 1309, - 1342, - 1375, - 1408, - 1430, - 1452, - 1474, - 1496, - 1518, - 1540, - 1562, - 1584, - 1606, - 1633, - 1660, - 1682, - 1704, - 1726, - 1748, - 1770, - 1792, - 1819, - 1849, - 1871, - 1893, - 1920, - 1942 + 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": [ - 1969 + 2025 ], "errorMessage": "can only call when creating" }, { "pc": [ 421, - 454, - 487, - 520, - 553, - 586, - 619, - 652, - 685, - 718, - 751, - 784, - 817, - 850, - 883, - 916, - 949, - 982, - 1015, - 1048, - 1081, - 1114, - 1147, - 1180, - 1213, - 1246, - 1279, - 1312, - 1345, - 1378, - 1411, - 1433, - 1455, - 1477, - 1499, - 1521, - 1543, - 1565, - 1587, - 1609, - 1636, - 1663, - 1685, - 1707, - 1729, - 1751, - 1773, - 1795, - 1822, - 1852, - 1874, - 1896, - 1923, - 1945 + 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": [ - 1982, - 1995, - 2011, - 2022, - 2038, + 2036, 2049, 2065, - 2078, - 2094, - 2107, - 2123, - 2136, - 2152, - 2163, - 2180, - 2191, - 2208, - 2221, - 2237, - 2250, - 2266, - 2279, - 2299, - 2310, - 2328, - 2339, - 2358, - 2371, - 2387, - 2400, - 2420, - 2433, - 2453, - 2464, - 2482, - 2493, - 2512, - 2525, - 2541, - 2554, - 2574, - 2587, - 2607, - 2618, - 2636, - 2647, - 2666, - 2679, - 2695, - 2708, - 2728, - 2741, - 2761, - 2772, - 2790, - 2801, - 2820, - 2833, - 2849, - 2862, - 2883, - 2900, - 2916 + 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" } @@ -1514,9 +1773,197 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5hcHByb3ZhbFByb2dyYW06CiAgICBpbnRjYmxvY2sgMSA4IDY0IDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NSAweDAwCiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A1OAogICAgcHVzaGJ5dGVzcyAweDk2ZjE0MTE2IDB4ZWQ2NjYwOTYgMHgyY2EwMzUyYiAweDg1OTA3ZDQwIDB4NGViMmFmNGEgMHgyY2JlYzQ1YiAweDA3NjY2ZmQ5IDB4MzcwYmFiZDMgMHgyYjZiM2VmMCAweDI3ZTIxYTk4IDB4MzM5ZGE5N2MgMHg3ODk4ZWQ5NyAweDFmMTMwY2VjIDB4Yzc0ODY2NGUgMHhhMmJhYzE0YiAweDdhNDYwY2IxIDB4ZGNhYjFmMDEgMHg5N2Q5MDY0ZCAweGNlMDZjMmEwIDB4N2MxMWUzNzUgMHhkY2RiY2VlMCAweDc3YTRiNjhkIDB4NGY1NDA2MjYgMHgwOTVhZWQ0MSAweGRmNzhjZGM2IDB4ZTNiN2U5MTggMHg1NTMzNzAwOCAweDliYjFjZDY2IDB4ODE0ODRkOWQgMHg3OWU5Y2IwMyAweDlhMDNkZjEwIDB4ZDNmMGU0NGIgMHg2NzNkYjJiZCAweDk4MmRiMjMzIDB4YWZmYmRmMGUgMHg4ZTRhMzBmNyAweDI4OGFmNzZlIDB4OGJkODRhMDQgMHhmY2Q1NWUxZiAweDBmMTU3NGZlIDB4YjJjYjEzYmUgMHhkMDU5ZWVhNyAweDRjYzRjMTU3IDB4M2QxN2FjNmUgMHhmN2YzZDVmYyAweGY4YzhmOGQ1IDB4NDNmNzE2MmEgMHg0MmUwOTA3NSAweGQ5NTZmNTc1IDB4NmMwMTYwZGYgMHhhODkwMTUwYiAweDBiMmY0YzNmIDB4OWRiOWQzMjcgMHhlNGQ5NTBhMSAvLyBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfZXEoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX25lKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9sdChieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl91aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV9ieXRlX2J5dGVfbGUoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fdWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYnl0ZVtdLGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9ieXRlX2d0KGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGJ5dGVbXSxieXRlW10pYm9vbCIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfYnl0ZV9nZShieXRlW10sYnl0ZVtdKWJvb2wiLCBtZXRob2QgInZlcmlmeV91aW50bl9pbml0KGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9pbml0KGJ5dGVbXSl1aW50MjU2IiwgbWV0aG9kICJ2ZXJpZnlfYnl0ZV9pbml0KGJ5dGVbXSlieXRlIiwgbWV0aG9kICJ2ZXJpZnlfdWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDMyIiwgbWV0aG9kICJ2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhieXRlW10pYnl0ZSIsIG1ldGhvZCAidmVyaWZ5X3VpbnRuX2Zyb21fbG9nKGJ5dGVbXSl1aW50MzIiLCBtZXRob2QgInZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZyhieXRlW10pdWludDI1NiIsIG1ldGhvZCAidmVyaWZ5X2J5dGVfZnJvbV9sb2coYnl0ZVtdKWJ5dGUiLCBtZXRob2QgInZlcmlmeV91Zml4ZWRueG1fYnl0ZXModWZpeGVkMzJ4OClieXRlW10iLCBtZXRob2QgInZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXModWZpeGVkMjU2eDE2KWJ5dGVbXSIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGJ5dGVbXSl1Zml4ZWQzMng4IiwgbWV0aG9kICJ2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMoYnl0ZVtdKXVmaXhlZDI1NngxNiIsIG1ldGhvZCAidmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMzJ4OCIsIG1ldGhvZCAidmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhieXRlW10pdWZpeGVkMjU2eDE2IiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2luaXQoc3RyaW5nKXN0cmluZyIsIG1ldGhvZCAidmVyaWZ5X3N0cmluZ19hZGQoc3RyaW5nLHN0cmluZylzdHJpbmciLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZXEoc3RyaW5nLHN0cmluZylib29sIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2J5dGVzKHN0cmluZylieXRlW10iLCBtZXRob2QgInZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcyhieXRlW10pc3RyaW5nIiwgbWV0aG9kICJ2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nKGJ5dGVbXSlzdHJpbmciLCBtZXRob2QgInZlcmlmeV9ib29sX2J5dGVzKGJvb2wpYnl0ZVtdIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGJ5dGVbXSlib29sIiwgbWV0aG9kICJ2ZXJpZnlfYm9vbF9mcm9tX2xvZyhieXRlW10pYm9vbCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9lcV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbmVfcm91dGVANyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbmVfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbmVfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbHRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sdF9yb3V0ZUAxNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbHRfcm91dGVAMTUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sdF9yb3V0ZUAxNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fbGVfcm91dGVAMTcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlX3JvdXRlQDE4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fbGVfcm91dGVAMjAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9sZV9yb3V0ZUAyMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjUgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ2Vfcm91dGVAMjcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9nZV9yb3V0ZUAyOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ2Vfcm91dGVAMzAgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9nZV9yb3V0ZUAzMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5faW5pdF9yb3V0ZUAzMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5faW5pdF9yb3V0ZUAzMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9pbml0X3JvdXRlQDM0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzX3JvdXRlQDM2IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fYnl0ZXNfcm91dGVAMzcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9mcm9tX2xvZ19yb3V0ZUAzOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2xvZ19yb3V0ZUA0MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQxIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXNfcm91dGVANDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9ieXRlc19yb3V0ZUA0NCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfYWRkX3JvdXRlQDQ4IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDkgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19ieXRlc19yb3V0ZUA1MCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2Zyb21fYnl0ZXNfcm91dGVANTEgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9ieXRlc19yb3V0ZUA1MyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2J5dGVzX3JvdXRlQDU0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fbG9nX3JvdXRlQDU1CiAgICBpbnRjXzMgLy8gMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZXFfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9lcV9yb3V0ZUAzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZXFfcm91dGVANDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxX3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZXFfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9lcQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9uZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbmUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbmVfcm91dGVAODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lX3JvdXRlQDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZV9yb3V0ZUAxMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX25lCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9uZV9yb3V0ZUAxMToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9uZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sdF9yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0X3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fbHQKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fbHRfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0X3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfbHRfcm91dGVAMTY6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9sdAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl91aW50bl9sZV9yb3V0ZUAxNzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fdWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fdWludG5fbGVfcm91dGVAMTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlX3JvdXRlQDE5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9iaWd1aW50bl9sZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZV9yb3V0ZUAyMDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9ieXRlX2xlX3JvdXRlQDIxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ieXRlX2J5dGVfbGUKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fdWludG5fZ3Rfcm91dGVAMjI6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTY1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0X3JvdXRlQDIzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl91aW50bl9ndAogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9iaWd1aW50bl9ndF9yb3V0ZUAyNDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWludG5fYmlndWludG5fZ3QKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3Rfcm91dGVAMjU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2J5dGVfYnl0ZV9ndF9yb3V0ZUAyNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9ieXRlX2d0CiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX3VpbnRuX2dlX3JvdXRlQDI3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl91aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl91aW50bl9nZV9yb3V0ZUAyODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fdWludG5fZ2UKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fYmlndWludG5fZ2Vfcm91dGVAMjk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlCiAgICBieXRlY18xIC8vIDB4MDAKICAgIGludGNfMyAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlX3JvdXRlQDMwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2J5dGVfZ2Vfcm91dGVAMzE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfYnl0ZV9nZQogICAgYnl0ZWNfMSAvLyAweDAwCiAgICBpbnRjXzMgLy8gMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91aW50bl9pbml0X3JvdXRlQDMyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2luaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9iaWd1aW50bl9pbml0X3JvdXRlQDMzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VpbnRuX2luaXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2luaXRfcm91dGVAMzQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYnl0ZV9pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfdWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91aW50bl9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlc19yb3V0ZUAzNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzX3JvdXRlQDM3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VpbnRuX2Zyb21fbG9nX3JvdXRlQDM4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VpbnRuX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWludG5fZnJvbV9sb2dfcm91dGVAMzk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWludG5fZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ieXRlX2Zyb21fbG9nX3JvdXRlQDQwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2J5dGVfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fYnl0ZXNfcm91dGVANDE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV91Zml4ZWRueG1fYnl0ZXMKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzX3JvdXRlQDQyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzX3JvdXRlQDQzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXNfcm91dGVANDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fYnl0ZXMKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2dfcm91dGVANDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nX3JvdXRlQDQ2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19pbml0X3JvdXRlQDQ3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19pbml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2FkZF9yb3V0ZUA0ODoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19hZGQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZXFfcm91dGVANDk6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZXEKICAgIGJ5dGVjXzEgLy8gMHgwMAogICAgaW50Y18zIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfc3RyaW5nX2J5dGVzX3JvdXRlQDUwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X3N0cmluZ19ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlc19yb3V0ZUA1MToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9ieXRlcwogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3N0cmluZ19mcm9tX2xvZ19yb3V0ZUA1MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9zdHJpbmdfZnJvbV9sb2cKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2J5dGVzX3JvdXRlQDUzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQKICAgIC8vIGV4cG9ydCBjbGFzcyBBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QgZXh0ZW5kcyBDb250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYm9vbF9ieXRlcwogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9ib29sX2Zyb21fYnl0ZXNfcm91dGVANTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYm9vbF9mcm9tX2xvZ19yb3V0ZUA1NToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9ib29sX2Zyb21fbG9nCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANTg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NAogICAgLy8gZXhwb3J0IGNsYXNzIEFyYzRQcmltaXRpdmVPcHNDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYyCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBjcmVhdGluZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA2MjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo0CiAgICAvLyBleHBvcnQgY2xhc3MgQXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0IGV4dGVuZHMgQ29udHJhY3QgewogICAgaW50Y18zIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUtNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExCiAgICAvLyByZXR1cm4gYVVpbnROID09PSBiVWludE4KICAgID09CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMy0xNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5CiAgICAvLyByZXR1cm4gYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEtMjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2VxKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gcmV0dXJuIGFVaW50Ti5ieXRlcy5lcXVhbHMoYlVpbnROLmJ5dGVzKQogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2VxOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5LTMwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzUKICAgIC8vIHJldHVybiBhVWludE4gPT09IGJVaW50TgogICAgPT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZXEoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZXE6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzctMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9lcShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQzCiAgICAvLyByZXR1cm4gYUJ5dGUgPT09IGJCeXRlCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fdWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDUtNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDkKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIHJldHVybiBhVWludE4gIT09IGJVaW50TgogICAgIT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUzLTU0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9uZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjU3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo1OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTkKICAgIC8vIHJldHVybiAhYVVpbnROLmJ5dGVzLmVxdWFscyhiVWludE4uYnl0ZXMpCiAgICA9PQogICAgIQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fbmU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjEtNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX25lKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjY2CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2NwogICAgLy8gcmV0dXJuICFhVWludE4uYnl0ZXMuZXF1YWxzKGJVaW50Ti5ieXRlcykKICAgID09CiAgICAhCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9uZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo3MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyByZXR1cm4gYVVpbnROICE9PSBiVWludE4KICAgICE9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX25lKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX25lOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc3LTc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbmUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gcmV0dXJuIGFCeXRlICE9PSBiQnl0ZQogICAgIT0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg1LTg2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTAKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkzLTk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo5OAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDwgQmlnVWludChiVWludE4ubmF0aXZlKQogICAgYnRvaQogICAgaXRvYgogICAgYjwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9sdChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwMS0xMDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNwogICAgLy8gcmV0dXJuIEJpZ1VpbnQoYVVpbnROLm5hdGl2ZSkgPCBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA5LTExMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fYmlndWludG5fbHQoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTMKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTQKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE1CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8IGJVaW50Ti5uYXRpdmUKICAgIGI8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2x0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2x0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNy0xMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9sdChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlIDwgYkJ5dGUubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUtMTI2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBidG9pCiAgICA8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYmlndWludG5fdWludG5fbGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMzLTEzNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fdWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxMzcKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzOAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM5CiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA8PSBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0MS0xNDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2xlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTQ1CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDYKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw1MTI+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMiAvLyA2NAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18yIC8vIDY0CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE0NwogICAgLy8gcmV0dXJuIEJpZ1VpbnQoYVVpbnROLm5hdGl2ZSkgPD0gYlVpbnROLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgaXRvYgogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNDktMTUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9sZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE1NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlIDw9IGJVaW50Ti5uYXRpdmUKICAgIGI8PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2J5dGVfYnl0ZV9sZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2J5dGVfYnl0ZV9sZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNTctMTU4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ieXRlX2J5dGVfbGUoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjEKICAgIC8vIGNvbnN0IGFCeXRlID0gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBkaWcgMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjIKICAgIC8vIGNvbnN0IGJCeXRlID0gbmV3IEJ5dGUoYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2MwogICAgLy8gcmV0dXJuIGFCeXRlLm5hdGl2ZSA8PSBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIDw9CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWludG5fdWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV91aW50bl91aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNjUtMTY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE2OQogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDY0PihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18xIC8vIDgKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3MAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDY0PihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gOAogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTcxCiAgICAvLyByZXR1cm4gYVVpbnROLm5hdGl2ZSA+IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl91aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3My0xNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTc3CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxNzgKICAgIC8vIGNvbnN0IGJVaW50TiA9IG5ldyBVaW50Tjw2ND4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE3OQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPiBCaWdVaW50KGJVaW50Ti5uYXRpdmUpCiAgICBidG9pCiAgICBpdG9iCiAgICBiPgogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2d0KGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTgxLTE4MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE4NgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTg3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA+IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI8CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fYmlndWludG5fZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxODktMTkwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9ndChhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5MwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjE5NAogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoxOTUKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID4gYlVpbnROLm5hdGl2ZQogICAgYj4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2J5dGVfZ3QoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9ieXRlX2J5dGVfZ3Q6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTk3LTE5OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYnl0ZV9ieXRlX2d0KGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAxCiAgICAvLyBjb25zdCBhQnl0ZSA9IG5ldyBCeXRlKGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzAgLy8gMQogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjAyCiAgICAvLyBjb25zdCBiQnl0ZSA9IG5ldyBCeXRlKGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMCAvLyAxCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMDMKICAgIC8vIHJldHVybiBhQnl0ZS5uYXRpdmUgPiBiQnl0ZS5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID4KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3VpbnRuX3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIwNS0yMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VpbnRuX3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjA5CiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NjQ+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjEwCiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTEKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID49IGJVaW50Ti5uYXRpdmUKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgID49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fdWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9iaWd1aW50bl91aW50bl9nZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTMtMjE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9iaWd1aW50bl91aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIxNwogICAgLy8gY29uc3QgYVVpbnROID0gbmV3IFVpbnROPDUxMj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjE4CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NjQ+KGJCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGludGNfMSAvLyA4CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gOAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMTkKICAgIC8vIHJldHVybiBhVWludE4ubmF0aXZlID49IEJpZ1VpbnQoYlVpbnROLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGl0b2IKICAgIGI+PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfdWludG5fYmlndWludG5fZ2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIxLTIyMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5fYmlndWludG5fZ2UoYTogYnl0ZXMsIGI6IGJ5dGVzKTogYm9vbGVhbiB7CiAgICBwcm90byAyIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyMjUKICAgIC8vIGNvbnN0IGFVaW50TiA9IG5ldyBVaW50Tjw2ND4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgaW50Y18xIC8vIDgKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyA4CiAgICBiemVybwogICAgZnJhbWVfZGlnIC0yCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyNgogICAgLy8gY29uc3QgYlVpbnROID0gbmV3IFVpbnROPDUxMj4oYkJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18yIC8vIDY0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzIgLy8gNjQKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjI3CiAgICAvLyByZXR1cm4gQmlnVWludChhVWludE4ubmF0aXZlKSA+PSBiVWludE4ubmF0aXZlCiAgICBzd2FwCiAgICBidG9pCiAgICBpdG9iCiAgICBiPD0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9iaWd1aW50bl9nZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIyOS0yMzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VpbnRuX2JpZ3VpbnRuX2dlKGE6IGJ5dGVzLCBiOiBieXRlcyk6IGJvb2xlYW4gewogICAgcHJvdG8gMiAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjMzCiAgICAvLyBjb25zdCBhVWludE4gPSBuZXcgVWludE48NTEyPihhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMiAvLyA2NAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMgogICAgZGlnIDEKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjM0CiAgICAvLyBjb25zdCBiVWludE4gPSBuZXcgVWludE48NTEyPihiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzIgLy8gNjQKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNQogICAgLy8gcmV0dXJuIGFVaW50Ti5uYXRpdmUgPj0gYlVpbnROLm5hdGl2ZQogICAgYj49CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9ieXRlX2dlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYnl0ZV9ieXRlX2dlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjIzNy0yMzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfYnl0ZV9nZShhOiBieXRlcywgYjogYnl0ZXMpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MQogICAgLy8gY29uc3QgYUJ5dGUgPSBuZXcgQnl0ZShhQmlndWludCkKICAgIGZyYW1lX2RpZyAtMgogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgaW50Y18wIC8vIDEKICAgIGJ6ZXJvCiAgICBmcmFtZV9kaWcgLTIKICAgIGRpZyAxCiAgICBifAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI0MgogICAgLy8gY29uc3QgYkJ5dGUgPSBuZXcgQnl0ZShiQmlndWludCkKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzAgLy8gMQogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJ8CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQzCiAgICAvLyByZXR1cm4gYUJ5dGUubmF0aXZlID49IGJCeXRlLm5hdGl2ZQogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgPj0KICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9pbml0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VpbnRuX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjQ1LTI0NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfdWludG5faW5pdChhOiBieXRlcyk6IFVpbnROPDMyPiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNDgKICAgIC8vIHJldHVybiBuZXcgVWludE48MzI+KGFCaWd1aW50KQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIHB1c2hpbnQgNCAvLyA0CiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBwdXNoaW50IDQgLy8gNAogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9pbml0KGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRuX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUwLTI1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5faW5pdChhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjUzCiAgICAvLyByZXR1cm4gbmV3IFVpbnROPDI1Nj4oYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgcHVzaGludCAzMiAvLyAzMgogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgcHVzaGludCAzMiAvLyAzMgogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9pbml0OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI1NS0yNTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfaW5pdChhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjU4CiAgICAvLyByZXR1cm4gbmV3IEJ5dGUoYUJpZ3VpbnQpCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgaW50Y18wIC8vIDEKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMCAvLyAxCiAgICBiemVybwogICAgZnJhbWVfZGlnIC0xCiAgICBifAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VpbnRuX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWludG5fZnJvbV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNjAtMjYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVWludE48MzI+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2MgogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVaW50TjwzMj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1aW50bl9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VpbnRuX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY0LTI2NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fZnJvbV9ieXRlcyhhOiBieXRlcyk6IFVpbnROPDI1Nj4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjY2CiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFVpbnROPDI1Nj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9ieXRlX2Zyb21fYnl0ZXMoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYnl0ZV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2OC0yNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9ieXRlcyhhOiBieXRlcyk6IEJ5dGUgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcwCiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PEJ5dGU+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91aW50bl9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV91aW50bl9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzItMjczCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91aW50bl9mcm9tX2xvZyhhOiBieXRlcyk6IFVpbnROPDMyPiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyNzQKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VWludE48MzI+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYmlndWludG5fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWludG5fZnJvbV9sb2c6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjc2LTI3NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWludG5fZnJvbV9sb2coYTogYnl0ZXMpOiBVaW50TjwyNTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3OAogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVaW50TjwyNTY+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYnl0ZV9mcm9tX2xvZyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ieXRlX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MC0yODEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2J5dGVfZnJvbV9sb2coYTogYnl0ZXMpOiBCeXRlIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4MgogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxCeXRlPihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfdWZpeGVkbnhtX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9ieXRlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyODQtMjg1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV91Zml4ZWRueG1fYnl0ZXMoYTogVUZpeGVkTnhNPDMyLCA4Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI4NgogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9iaWd1Zml4ZWRueG1fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6Mjg4LTI4OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYmlndWZpeGVkbnhtX2J5dGVzKGE6IFVGaXhlZE54TTwyNTYsIDE2Pik6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5MAogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Mi0yOTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDMyLCA4PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czoyOTQKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VUZpeGVkTnhNPDMyLCA4Pj4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5Ni0yOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogVUZpeGVkTnhNPDI1NiwgMTY+IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI5OAogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxVRml4ZWROeE08MjU2LCAxNj4+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV91Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfdWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwMC0zMDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwzMiwgOD4gewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzAyCiAgICAvLyByZXR1cm4gaW50ZXJwcmV0QXNBcmM0PFVGaXhlZE54TTwzMiwgOD4+KGEsICdsb2cnKQogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDQgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgNAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICA9PQogICAgYXNzZXJ0IC8vIEJ5dGVzIGhhcyB2YWxpZCBwcmVmaXgKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9iaWd1Zml4ZWRueG1fZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYmlndWZpeGVkbnhtX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMwNC0zMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2JpZ3VmaXhlZG54bV9mcm9tX2xvZyhhOiBieXRlcyk6IFVGaXhlZE54TTwyNTYsIDE2PiB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMDYKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8VUZpeGVkTnhNPDI1NiwgMTY+PihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2luaXQoYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2luaXQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzA4LTMwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2luaXQoYTogc3RyaW5nKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxMAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihgSGVsbG8sICR7YX1gKQogICAgcHVzaGJ5dGVzICJIZWxsbywgIgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzExCiAgICAvLyByZXR1cm4gcmVzdWx0CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfc3RyaW5nX2FkZChhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2FkZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTMtMzE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfYWRkKGE6IFN0ciwgYjogU3RyKTogU3RyIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMxNQogICAgLy8gY29uc3QgcmVzdWx0ID0gYS5uYXRpdmUuY29uY2F0KGIubmF0aXZlKQogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgY29uY2F0CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzE2CiAgICAvLyByZXR1cm4gbmV3IFN0cihyZXN1bHQpCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19lcShhOiBieXRlcywgYjogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X3N0cmluZ19lcToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMTgtMzE5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9zdHJpbmdfZXEoYTogU3RyLCBiOiBTdHIpOiBib29sZWFuIHsKICAgIHByb3RvIDIgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyMAogICAgLy8gcmV0dXJuIGEgPT09IGIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9zdHJpbmdfYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIyLTMyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfc3RyaW5nX2J5dGVzKGE6IHN0cmluZyk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNAogICAgLy8gY29uc3QgcmVzdWx0ID0gbmV3IFN0cihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNQogICAgLy8gcmV0dXJuIHJlc3VsdC5ieXRlcwogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyNy0zMjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2J5dGVzKGE6IGJ5dGVzKTogU3RyIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMyOQogICAgLy8gcmV0dXJuIGludGVycHJldEFzQXJjNDxTdHI+KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czo6QXJjNFByaW1pdGl2ZU9wc0NvbnRyYWN0LnZlcmlmeV9zdHJpbmdfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfc3RyaW5nX2Zyb21fbG9nOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzMS0zMzIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X3N0cmluZ19mcm9tX2xvZyhhOiBieXRlcyk6IFN0ciB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozMzMKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8U3RyPihhLCAnbG9nJykKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCA0IDAKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBCeXRlcyBoYXMgdmFsaWQgcHJlZml4CiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC52ZXJpZnlfYm9vbF9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNS0zMzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2Jvb2xfYnl0ZXMoYTogQm9vbCk6IGJ5dGVzIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzNwogICAgLy8gcmV0dXJuIGEuYnl0ZXMKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9ieXRlcyhhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9ib29sX2Zyb21fYnl0ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzM5LTM0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYm9vbF9mcm9tX2J5dGVzKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDEKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qm9vbD4oYSkKICAgIGZyYW1lX2RpZyAtMQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL2FyYzQtcHJpbWl0aXZlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpBcmM0UHJpbWl0aXZlT3BzQ29udHJhY3QudmVyaWZ5X2Jvb2xfZnJvbV9sb2coYTogYnl0ZXMpIC0+IGJ5dGVzOgp2ZXJpZnlfYm9vbF9mcm9tX2xvZzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDMtMzQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9ib29sX2Zyb21fbG9nKGE6IGJ5dGVzKTogQm9vbCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9hcmM0LXByaW1pdGl2ZS1vcHMvY29udHJhY3QuYWxnby50czozNDUKICAgIC8vIHJldHVybiBpbnRlcnByZXRBc0FyYzQ8Qm9vbD4oYSwgJ2xvZycpCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgNCAwCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQnl0ZXMgaGFzIHZhbGlkIHByZWZpeAogICAgcmV0c3ViCg==", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvYXJjNC1wcmltaXRpdmUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OkFyYzRQcmltaXRpdmVPcHNDb250cmFjdC5jbGVhclN0YXRlUHJvZ3JhbToKICAgIHB1c2hpbnQgMSAvLyAxCiAgICByZXR1cm4K" + "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": [], + "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 index 2bdc696..a4d5804 100644 --- a/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.clear.teal +++ b/tests/artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.clear.teal @@ -1,5 +1,7 @@ #pragma version 10 +#pragma typetrack false -tests/artifacts/arc4-primitive-ops/contract.algo.ts::Arc4PrimitiveOpsContract.clearStateProgram: +// @algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract.clearStateProgram() -> uint64: +main: pushint 1 // 1 return From 3ffe395fe06a67e1d918e35fada54eeae5fe48b4 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Tue, 24 Dec 2024 15:59:47 +0800 Subject: [PATCH 77/85] feat: implement stubs for compile functions --- examples/precompiled/contract.algo.ts | 136 ++++++++++++++++++ examples/precompiled/contract.spec.ts | 81 +++++++++++ examples/precompiled/precompiled-apps.algo.ts | 65 +++++++++ examples/rollup.config.ts | 1 + package-lock.json | 9 +- package.json | 2 +- src/impl/compiled.ts | 55 +++++++ src/impl/encoded-types.ts | 9 +- src/impl/inner-transactions.ts | 12 +- src/runtime-helpers.ts | 1 + src/subcontexts/ledger-context.ts | 24 +++- src/test-execution-context.ts | 37 ++++- src/test-transformer/visitors.ts | 2 +- src/typescript-helpers.ts | 1 + 14 files changed, 420 insertions(+), 15 deletions(-) create mode 100644 examples/precompiled/contract.algo.ts create mode 100644 examples/precompiled/contract.spec.ts create mode 100644 examples/precompiled/precompiled-apps.algo.ts create mode 100644 src/impl/compiled.ts diff --git a/examples/precompiled/contract.algo.ts b/examples/precompiled/contract.algo.ts new file mode 100644 index 0000000..abce1ec --- /dev/null +++ b/examples/precompiled/contract.algo.ts @@ -0,0 +1,136 @@ +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 { 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')], + approvalProgram: compiled.approvalProgram, + clearStateProgram: compiled.clearStateProgram, + globalNumBytes: 1, + }) + .submit().createdApp + + const txn = itxn + .applicationCall({ + appArgs: [methodSelector('greet(string)string'), encodeArc4('world')], + appId: helloApp, + }) + .submit() + const result = decodeArc4(txn.lastLog, 'log') + + assert(result === 'hello world') + + itxn + .applicationCall({ + appId: helloApp, + appArgs: [methodSelector('delete()void')], + onCompletion: OnCompleteAction.DeleteApplication, + }) + .submit() + } + + test_compile_contract_with_template() { + const compiled = compile(HelloTemplate, { templateVars: { GREETING: 'hey' } }) + + const helloApp = itxn + .applicationCall({ + appArgs: [methodSelector('create()void')], + approvalProgram: compiled.approvalProgram, + clearStateProgram: compiled.clearStateProgram, + globalNumBytes: 1, + }) + .submit().createdApp + + const txn = itxn + .applicationCall({ + appArgs: [methodSelector('greet(string)string'), encodeArc4('world')], + appId: helloApp, + }) + .submit() + const result = decodeArc4(txn.lastLog, 'log') + + assert(result === 'hey world') + + itxn + .applicationCall({ + appId: helloApp, + appArgs: [methodSelector('delete()void')], + onCompletion: OnCompleteAction.DeleteApplication, + }) + .submit() + } + + test_compile_contract_with_template_and_custom_prefix() { + const compiled = compile(HelloTemplateCustomPrefix, { templateVars: { GREETING: 'bonjour' }, templateVarsPrefix: 'PRFX_' }) + + const helloApp = itxn + .applicationCall({ + appArgs: [methodSelector('create()void')], + approvalProgram: compiled.approvalProgram, + clearStateProgram: compiled.clearStateProgram, + globalNumBytes: 1, + }) + .submit().createdApp + + const txn = itxn + .applicationCall({ + appArgs: [methodSelector('greet(string)string'), encodeArc4('world')], + appId: helloApp, + }) + .submit() + const result = decodeArc4(txn.lastLog, 'log') + + assert(result === 'bonjour world') + + itxn + .applicationCall({ + appId: helloApp, + appArgs: [methodSelector('delete()void')], + onCompletion: OnCompleteAction.DeleteApplication, + }) + .submit() + } + + test_compile_contract_large() { + const compiled = compile(LargeProgram) + + const largeApp = itxn + .applicationCall({ + approvalProgram: compiled.approvalProgram, + clearStateProgram: compiled.clearStateProgram, + extraProgramPages: compiled.extraProgramPages, + globalNumBytes: compiled.globalBytes, + }) + .submit().createdApp + + const txn = itxn + .applicationCall({ + appArgs: [methodSelector('getBigBytesLength()uint64')], + appId: largeApp, + }) + .submit() + const result = decodeArc4(txn.lastLog, 'log') + + assert(result === 4096) + + itxn + .applicationCall({ + appId: largeApp, + appArgs: [methodSelector('delete()void')], + onCompletion: OnCompleteAction.DeleteApplication, + }) + .submit() + } + + test_compile_logic_sig(account: bytes) { + const compiled = compile(TerribleCustodialAccount) + + assert(compiled.account.bytes === account) + } +} diff --git a/examples/precompiled/contract.spec.ts b/examples/precompiled/contract.spec.ts new file mode 100644 index 0000000..5f85484 --- /dev/null +++ b/examples/precompiled/contract.spec.ts @@ -0,0 +1,81 @@ +import { arc4 } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, it } from 'vitest' +import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_BYTES_SIZE } from '../../src/constants' +import { asUint64Cls } from '../../src/util' +import { HelloFactory } from './contract.algo' +import { Hello, HelloTemplate, HelloTemplateCustomPrefix, LargeProgram, TerribleCustodialAccount } from './precompiled-apps.algo' + +describe('pre compiled app calls', () => { + const ctx = new TestExecutionContext() + afterEach(() => { + ctx.reset() + }) + + it('should be able to compile and call a precompiled app', () => { + // Arrange + const helloApp = ctx.any.application({ + approvalProgram: ctx.any.bytes(20), + appLogs: [ABI_RETURN_VALUE_LOG_PREFIX.concat(new arc4.Str('hello world').bytes)], + }) + ctx.setCompiledApp(Hello, helloApp.id) + + const contract = ctx.contract.create(HelloFactory) + + // Act + contract.test_compile_contract() + }) + + it('should be able to compile with template vars and call a precompiled app', () => { + // Arrange + const helloTemplateApp = ctx.any.application({ + approvalProgram: ctx.any.bytes(20), + appLogs: [ABI_RETURN_VALUE_LOG_PREFIX.concat(new arc4.Str('hey world').bytes)], + }) + ctx.setCompiledApp(HelloTemplate, helloTemplateApp.id) + + const contract = ctx.contract.create(HelloFactory) + + // Act + contract.test_compile_contract_with_template() + }) + + it('should be able to compile with template vars and custom prefix', () => { + // Arrange + const helloTemplateCustomPrefixApp = ctx.any.application({ + approvalProgram: ctx.any.bytes(20), + appLogs: [ABI_RETURN_VALUE_LOG_PREFIX.concat(new arc4.Str('bonjour world').bytes)], + }) + ctx.setCompiledApp(HelloTemplateCustomPrefix, helloTemplateCustomPrefixApp.id) + + const contract = ctx.contract.create(HelloFactory) + + // Act + contract.test_compile_contract_with_template_and_custom_prefix() + }) + + it('should be able to compile large program', () => { + // Arrange + const largeProgramApp = ctx.any.application({ + approvalProgram: ctx.any.bytes(20), + appLogs: [ABI_RETURN_VALUE_LOG_PREFIX.concat(asUint64Cls(MAX_BYTES_SIZE).toBytes().asAlgoTs())], + }) + ctx.setCompiledApp(LargeProgram, largeProgramApp.id) + + const contract = ctx.contract.create(HelloFactory) + + // Act + contract.test_compile_contract_large() + }) + + it('should be able to compile logic sig', () => { + // Arrange + const terribleCustodialAccount = ctx.any.account() + ctx.setCompiledLogicSig(TerribleCustodialAccount, terribleCustodialAccount) + + const contract = ctx.contract.create(HelloFactory) + + // Act + contract.test_compile_logic_sig(terribleCustodialAccount.bytes) + }) +}) diff --git a/examples/precompiled/precompiled-apps.algo.ts b/examples/precompiled/precompiled-apps.algo.ts new file mode 100644 index 0000000..bdec103 --- /dev/null +++ b/examples/precompiled/precompiled-apps.algo.ts @@ -0,0 +1,65 @@ +import { abimethod, Contract, GlobalState, LogicSig, op, TemplateVar } from '@algorandfoundation/algorand-typescript' + +abstract class HelloBase extends Contract { + greeting = GlobalState({ initialValue: '' }) + + @abimethod({ allowActions: 'DeleteApplication' }) + delete() {} + + @abimethod({ allowActions: 'UpdateApplication' }) + update() {} + + greet(name: string): string { + return `${this.greeting.value} ${name}` + } +} + +export class Hello extends HelloBase { + @abimethod({ onCreate: 'require' }) + create(greeting: string) { + this.greeting.value = greeting + } +} + +export class HelloTemplate extends HelloBase { + constructor() { + super() + this.greeting.value = TemplateVar('GREETING') + } + + @abimethod({ onCreate: 'require' }) + create() {} +} + +export class HelloTemplateCustomPrefix extends HelloBase { + constructor() { + super() + this.greeting.value = TemplateVar('GREETING', 'PRFX_') + } + + @abimethod({ onCreate: 'require' }) + create() {} +} + +function getBigBytes() { + return op.bzero(4096) +} + +export class LargeProgram extends Contract { + getBigBytesLength() { + return getBigBytes().length + } + + @abimethod({ allowActions: 'DeleteApplication' }) + delete() {} +} + +/** + * This logic sig can be used to create a custodial account that will allow any transaction to transfer its + * funds/assets. + */ +export class TerribleCustodialAccount extends LogicSig { + program() { + return true + } +} diff --git a/examples/rollup.config.ts b/examples/rollup.config.ts index 79ef1aa..d16a189 100644 --- a/examples/rollup.config.ts +++ b/examples/rollup.config.ts @@ -13,6 +13,7 @@ const config: RollupOptions = { 'examples/voting/contract.algo.ts', 'examples/simple-voting/contract.algo.ts', 'examples/zk-whitelist/contract.algo.ts', + 'examples/precompiled/contract.algo.ts', ], output: [ { diff --git a/package-lock.json b/package-lock.json index c224f49..c4f787f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "hasInstallScript": true, "dependencies": { - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.23", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.24", "@algorandfoundation/puya-ts": "^1.0.0-alpha.36", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", @@ -73,9 +73,9 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "0.0.1-alpha.23", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-0.0.1-alpha.23.tgz", - "integrity": "sha512-hK1rom4MD2qn3tO03Bsui8lcuA7WF5CeFGdUCIrRJgc+wLnWKNx0s9TkAotrl8VwfD5Wg7Gn3u9txz4RgdQsPw==", + "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==", "peerDependencies": { "tslib": "^2.6.2" } @@ -13248,6 +13248,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 1996da5..c3001e9 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "tslib": "^2.6.2" }, "dependencies": { - "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.23", + "@algorandfoundation/algorand-typescript": "^0.0.1-alpha.24", "@algorandfoundation/puya-ts": "^1.0.0-alpha.36", "elliptic": "^6.5.7", "js-sha256": "^0.11.0", diff --git a/src/impl/compiled.ts b/src/impl/compiled.ts new file mode 100644 index 0000000..71aa7a2 --- /dev/null +++ b/src/impl/compiled.ts @@ -0,0 +1,55 @@ +import { + Account, + BaseContract, + CompileContractOptions, + CompiledContract, + CompiledLogicSig, + CompileLogicSigOptions, + LogicSig, +} from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' +import { ConstructorFor } from '../typescript-helpers' +import { ApplicationData } from './application' + +export function compileImpl( + artefact: ConstructorFor | ConstructorFor, + options?: CompileContractOptions | CompileLogicSigOptions, +): CompiledLogicSig | CompiledContract { + let app: ApplicationData | undefined + let account: Account | undefined + const compiledApp = lazyContext.value.getCompiledApp(artefact as ConstructorFor) + const compiledLogicSig = lazyContext.value.getCompiledLogicSig(artefact as ConstructorFor) + if (compiledApp !== undefined) { + app = lazyContext.ledger.applicationDataMap.get(compiledApp[1]) + } + if (compiledLogicSig !== undefined) { + account = compiledLogicSig[1] + } + if (options?.templateVars) { + Object.entries(options.templateVars).forEach(([key, value]) => { + lazyContext.value.setTemplateVar(key, value, options.templateVarsPrefix) + }) + } + return new Proxy({} as CompiledLogicSig | CompiledContract, { + get: (_target, prop) => { + switch (prop) { + case 'approvalProgram': + return app?.application.approvalProgram ?? [lazyContext.any.bytes(10), lazyContext.any.bytes(10)] + case 'clearStateProgram': + return app?.application.clearStateProgram ?? [lazyContext.any.bytes(10), lazyContext.any.bytes(10)] + case 'extraProgramPages': + return (options as CompileContractOptions)?.extraProgramPages ?? app?.application.extraProgramPages ?? lazyContext.any.uint64() + case 'globalUints': + return (options as CompileContractOptions)?.globalUints ?? app?.application.globalNumUint ?? lazyContext.any.uint64() + case 'globalBytes': + return (options as CompileContractOptions)?.globalBytes ?? app?.application.globalNumBytes ?? lazyContext.any.uint64() + case 'localUints': + return (options as CompileContractOptions)?.localUints ?? app?.application.localNumUint ?? lazyContext.any.uint64() + case 'localBytes': + return (options as CompileContractOptions)?.localBytes ?? app?.application.localNumBytes ?? lazyContext.any.uint64() + case 'account': + return account ?? lazyContext.any.account() + } + }, + }) +} diff --git a/src/impl/encoded-types.ts b/src/impl/encoded-types.ts index 162c5fb..1d50312 100644 --- a/src/impl/encoded-types.ts +++ b/src/impl/encoded-types.ts @@ -1185,11 +1185,14 @@ export const getArc4TypeName = (typeInfo: TypeInfo): string | undefined => { return undefined } -export function decodeArc4Impl(sourceTypeInfoString: string, bytes: internal.primitives.StubBytesCompat): T { +export function decodeArc4Impl( + sourceTypeInfoString: string, + bytes: internal.primitives.StubBytesCompat, + prefix: 'none' | 'log' = 'none', +): T { const sourceTypeInfo = JSON.parse(sourceTypeInfoString) const encoder = getArc4Encoder(sourceTypeInfo) - const source = encoder(bytes, sourceTypeInfo) - + const source = encoder(bytes, sourceTypeInfo, prefix) return getNativeValue(source) as T } diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts index ea68185..b2ec556 100644 --- a/src/impl/inner-transactions.ts +++ b/src/impl/inner-transactions.ts @@ -137,8 +137,17 @@ export class ApplicationInnerTxn extends ApplicationTransaction implements itxn. /* @internal */ constructor(fields: Mutable) { const { appId, approvalProgram, clearStateProgram, onCompletion, appArgs, accounts, assets, apps, ...rest } = mapCommonFields(fields) + const compiledApp = + appId === undefined && approvalProgram !== undefined + ? lazyContext.ledger.getApplicationForApprovalProgram(approvalProgram) + : undefined super({ - appId: appId instanceof internal.primitives.Uint64Cls ? getApp(appId) : (appId as Application), + appId: + appId === undefined && compiledApp + ? compiledApp + : appId instanceof internal.primitives.Uint64Cls + ? getApp(appId) + : (appId as Application), onCompletion: typeof onCompletion === 'string' ? (onCompletion as arc4.OnCompleteActionStr) @@ -153,6 +162,7 @@ export class ApplicationInnerTxn extends ApplicationTransaction implements itxn. accounts: accounts?.map((x) => x), assets: assets?.map((x) => x), apps: apps?.map((x) => x), + createdApp: compiledApp, ...rest, }) } diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index a620884..b16e975 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -7,6 +7,7 @@ import { 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' diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index b943539..e98688c 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -1,4 +1,4 @@ -import { Account, Application, Asset, BaseContract, internal, LocalStateForAccount } from '@algorandfoundation/algorand-typescript' +import { Account, Application, Asset, BaseContract, bytes, internal, LocalStateForAccount } from '@algorandfoundation/algorand-typescript' import { AccountMap, Uint64Map } from '../collections/custom-key-map' import { MAX_UINT64 } from '../constants' import { AccountData, AssetHolding } from '../impl/account' @@ -52,6 +52,28 @@ export class LedgerContext { throw internal.errors.internalError('Unknown contract, check correct testing context is active') } + getApplicationForApprovalProgram(approvalProgram: bytes | readonly bytes[] | undefined): Application | undefined { + if (approvalProgram === undefined) { + return undefined + } + const entries = this.applicationDataMap.entries() + let next = entries.next().value + let found = false + while (next && !found) { + found = next[1].application.approvalProgram === approvalProgram + if (!found) { + next = entries.next().value + } + } + if (found && next) { + const appId = asUint64(next[0]) + if (this.applicationDataMap.has(appId)) { + return Application(appId) + } + } + return undefined + } + /** * Update asset holdings for account, only specified values will be updated. * Account will also be opted-in to asset diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index efbf68e..af618ef 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -1,4 +1,4 @@ -import { Account, Application, Asset, bytes, internal, LogicSig, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, Application, Asset, BaseContract, bytes, internal, LogicSig, uint64 } from '@algorandfoundation/algorand-typescript' import { captureMethodConfig } from './abi-metadata' import { DEFAULT_TEMPLATE_VAR_PREFIX } from './constants' import { DecodedLogs, LogDecoding } from './decode-logs' @@ -19,7 +19,7 @@ import { Box, BoxMap, BoxRef, GlobalState, LocalState } from './impl/state' import { ContractContext } from './subcontexts/contract-context' import { LedgerContext } from './subcontexts/ledger-context' import { TransactionContext } from './subcontexts/transaction-context' -import { DeliberateAny } from './typescript-helpers' +import { ConstructorFor, DeliberateAny } from './typescript-helpers' import { getRandomBytes } from './util' import { ValueGenerator } from './value-generators' @@ -31,6 +31,8 @@ export class TestExecutionContext implements internal.ExecutionContext { #defaultSender: Account #activeLogicSigArgs: bytes[] #template_vars: Record = {} + #compiledApps: Array<[ConstructorFor, uint64]> = [] + #compiledLogicSigs: Array<[ConstructorFor, Account]> = [] constructor(defaultSenderAddress?: bytes) { internal.ctxMgr.instance = this @@ -142,8 +144,34 @@ export class TestExecutionContext implements internal.ExecutionContext { } } - setTemplateVar(name: string, value: DeliberateAny) { - this.#template_vars[DEFAULT_TEMPLATE_VAR_PREFIX + name] = value + setTemplateVar(name: string, value: DeliberateAny, prefix?: string) { + this.#template_vars[(prefix ?? DEFAULT_TEMPLATE_VAR_PREFIX) + name] = value + } + + getCompiledApp(contract: ConstructorFor) { + return this.#compiledApps.find(([c, _]) => c === contract) + } + + setCompiledApp(c: ConstructorFor, appId: uint64) { + const existing = this.getCompiledApp(c) + if (existing) { + existing[1] = appId + } else { + this.#compiledApps.push([c, appId]) + } + } + + getCompiledLogicSig(logicsig: ConstructorFor) { + return this.#compiledLogicSigs.find(([c, _]) => c === logicsig) + } + + setCompiledLogicSig(c: ConstructorFor, account: Account) { + const existing = this.getCompiledLogicSig(c) + if (existing) { + existing[1] = account + } else { + this.#compiledLogicSigs.push([c, account]) + } } reset() { @@ -152,6 +180,7 @@ export class TestExecutionContext implements internal.ExecutionContext { this.#txnContext = new TransactionContext() this.#activeLogicSigArgs = [] this.#template_vars = {} + this.#compiledApps = [] internal.ctxMgr.reset() internal.ctxMgr.instance = this } diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index fd686ae..fe9bf68 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -367,7 +367,7 @@ 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'] + const stubbedFunctionNames = ['interpretAsArc4', 'decodeArc4', 'encodeArc4', 'TemplateVar', 'ensureBudget', 'emit', 'compile'] return stubbedFunctionNames.includes(functionName) ? functionName : undefined } diff --git a/src/typescript-helpers.ts b/src/typescript-helpers.ts index d933a6c..82a9fd1 100644 --- a/src/typescript-helpers.ts +++ b/src/typescript-helpers.ts @@ -2,6 +2,7 @@ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ export type DeliberateAny = any export type AnyFunction = (...args: DeliberateAny[]) => DeliberateAny +export type ConstructorFor = new (...args: TArgs) => T export type Mutable = { -readonly [P in keyof T]: T[P] } From cd7b7a28315dc4df9478ea3ea669b4d2c071470f Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 27 Dec 2024 10:31:26 +0800 Subject: [PATCH 78/85] feat: implement stubs for urange, assertMatch and match functions --- src/impl/match.ts | 56 ++++++++++++++ src/impl/urange.ts | 18 +++++ src/runtime-helpers.ts | 2 + src/subcontexts/ledger-context.ts | 19 +++-- src/test-transformer/visitors.ts | 13 +++- tests/match.spec.ts | 122 ++++++++++++++++++++++++++++++ tests/urange.spec.ts | 57 ++++++++++++++ 7 files changed, 280 insertions(+), 7 deletions(-) create mode 100644 src/impl/match.ts create mode 100644 src/impl/urange.ts create mode 100644 tests/match.spec.ts create mode 100644 tests/urange.spec.ts diff --git a/src/impl/match.ts b/src/impl/match.ts new file mode 100644 index 0000000..da87e3f --- /dev/null +++ b/src/impl/match.ts @@ -0,0 +1,56 @@ +import { assert, assertMatch, internal, match } from '@algorandfoundation/algorand-typescript' +import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' +import { DeliberateAny } from '../typescript-helpers' +import { asBytes, asMaybeBigUintCls } from '../util' +import { BytesBackedCls, Uint64BackedCls } from './base' + +export const matchImpl: typeof match = (subject, test): boolean => { + const bigIntSubjectValue = getBigIntValue(subject) + if (bigIntSubjectValue !== undefined) { + const bigIntTestValue = getBigIntValue(test) + if (bigIntTestValue !== undefined) { + return bigIntSubjectValue === bigIntTestValue + } else if (Object.hasOwn(test, 'lessThan')) { + return bigIntSubjectValue < getBigIntValue((test as DeliberateAny).lessThan)! + } else if (Object.hasOwn(test, 'greaterThan')) { + return bigIntSubjectValue > getBigIntValue((test as DeliberateAny).greaterThan)! + } else if (Object.hasOwn(test, 'lessThanEq')) { + return bigIntSubjectValue <= getBigIntValue((test as DeliberateAny).lessThanEq)! + } else if (Object.hasOwn(test, 'greaterThanEq')) { + return bigIntSubjectValue >= getBigIntValue((test as DeliberateAny).greaterThanEq)! + } else if (Object.hasOwn(test, 'between')) { + 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 (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) + ) + } else if (subject instanceof ARC4Encoded) { + return subject.bytes.equals((test as unknown as ARC4Encoded).bytes) + } else if (Array.isArray(subject)) { + return (test as []).map((x, i) => matchImpl((subject as DeliberateAny)[i], x as DeliberateAny)).every((x) => x) + } else if (typeof subject === 'object') { + return Object.entries(test!) + .map(([k, v]) => matchImpl((subject as DeliberateAny)[k], v as DeliberateAny)) + .every((x) => x) + } + return false +} + +export const assertMatchImpl: typeof assertMatch = (subject, test, message): boolean => { + const isMatching = matchImpl(subject, test) + assert(isMatching, message) + return isMatching +} + +const getBigIntValue = (x: unknown) => { + return asMaybeBigUintCls(x)?.asBigInt() +} diff --git a/src/impl/urange.ts b/src/impl/urange.ts new file mode 100644 index 0000000..647e786 --- /dev/null +++ b/src/impl/urange.ts @@ -0,0 +1,18 @@ +import { internal } from '@algorandfoundation/algorand-typescript' +import { asBigInt, asUint64 } from '../util' + +export function* urangeImpl( + a: internal.primitives.StubUint64Compat, + b?: internal.primitives.StubUint64Compat, + c?: internal.primitives.StubUint64Compat, +) { + const start = b ? asBigInt(a) : BigInt(0) + const end = b ? asBigInt(b) : asBigInt(a) + const step = c ? asBigInt(c) : BigInt(1) + let iterationCount = 0 + for (let i = start; i < end; i += step) { + iterationCount++ + yield asUint64(i) + } + return iterationCount +} diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index b16e975..2edd1b5 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -12,7 +12,9 @@ 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 function switchableValue(x: unknown): bigint | string | boolean { if (typeof x === 'boolean') return x diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index e98688c..9062a48 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -27,6 +27,13 @@ export class LedgerContext { 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') + } + getAsset(assetId: internal.primitives.StubUint64Compat): Asset { if (this.assetDataMap.has(assetId)) { return Asset(asUint64(assetId)) @@ -57,16 +64,16 @@ export class LedgerContext { return undefined } const entries = this.applicationDataMap.entries() - let next = entries.next().value + let next = entries.next() let found = false - while (next && !found) { - found = next[1].application.approvalProgram === approvalProgram + while (!next.done && !found) { + found = next.value[1].application.approvalProgram === approvalProgram if (!found) { - next = entries.next().value + next = entries.next() } } - if (found && next) { - const appId = asUint64(next[0]) + if (found && next?.value) { + const appId = asUint64(next.value[0]) if (this.applicationDataMap.has(appId)) { return Application(appId) } diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index fe9bf68..8c69489 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -367,7 +367,18 @@ 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'] + const stubbedFunctionNames = [ + 'interpretAsArc4', + 'decodeArc4', + 'encodeArc4', + 'TemplateVar', + 'ensureBudget', + 'emit', + 'compile', + 'urange', + 'match', + 'assertMatch', + ] return stubbedFunctionNames.includes(functionName) ? functionName : undefined } diff --git a/tests/match.spec.ts b/tests/match.spec.ts new file mode 100644 index 0000000..aa04660 --- /dev/null +++ b/tests/match.spec.ts @@ -0,0 +1,122 @@ +import { assertMatch, biguint, 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' +import { StrImpl } from '../src/impl/encoded-types' +describe('match', () => { + const ctx = new TestExecutionContext() + + afterEach(async () => { + ctx.reset() + }) + + const numericTestData = [ + { subject: 1, test: 1, expected: true }, + { subject: 0, test: 1, expected: false }, + { subject: 1, test: 0, expected: false }, + { subject: 1, test: Uint64(1), expected: true }, + { subject: Uint64(1), test: Uint64(1), expected: true }, + { subject: Uint64(1), test: 1, expected: true }, + { subject: 42, test: MAX_UINT64, expected: false }, + { subject: Uint64(MAX_UINT64), test: Uint64(42), expected: false }, + { subject: BigUint(1), test: 1n, expected: true }, + { subject: 1n, test: BigUint(1), expected: true }, + { subject: BigUint(1), test: BigUint(1), expected: true }, + { subject: 42n, test: MAX_UINT512, expected: false }, + { subject: BigUint(MAX_UINT512), test: BigUint(42n), expected: false }, + { subject: { a: BigUint(MAX_UINT512) }, test: { a: { lessThan: MAX_UINT512 } }, expected: false }, + { subject: { a: BigUint(MAX_UINT512) }, test: { a: { lessThanEq: MAX_UINT64 } }, expected: false }, + { subject: { a: MAX_UINT64 }, test: { a: { lessThan: BigUint(MAX_UINT512) } }, expected: true }, + { subject: { a: MAX_UINT512 }, test: { a: { lessThanEq: BigUint(MAX_UINT512) } }, expected: true }, + { subject: { a: BigUint(MAX_UINT512) }, test: { a: { greaterThan: MAX_UINT512 } }, expected: false }, + { subject: { a: BigUint(MAX_UINT64) }, test: { a: { greaterThanEq: MAX_UINT512 } }, expected: false }, + { subject: { a: MAX_UINT512 }, test: { a: { greaterThan: BigUint(MAX_UINT64) } }, expected: true }, + { subject: { a: MAX_UINT512 }, test: { a: { greaterThanEq: BigUint(MAX_UINT512) } }, expected: true }, + { + subject: { a: MAX_UINT512 }, + test: { a: { between: [BigUint(MAX_UINT64), BigUint(MAX_UINT512)] as [biguint, biguint] } }, + expected: true, + }, + { + subject: { a: MAX_UINT64 }, + test: { a: { between: [BigUint(MAX_UINT64), BigUint(MAX_UINT512)] as [biguint, biguint] } }, + expected: true, + }, + { subject: { a: 42 }, test: { a: { between: [BigUint(MAX_UINT64), BigUint(MAX_UINT512)] as [biguint, biguint] } }, expected: false }, + ] + + const account1 = ctx.any.account() + const sameAccount = ctx.ledger.getAccount(account1) + const differentAccount = ctx.any.account() + + const app1 = ctx.any.application() + const sameApp = ctx.ledger.getApplication(app1.id) + const differentApp = ctx.any.application() + + const asset1 = ctx.any.asset() + const sameAsset = ctx.ledger.getAsset(asset1.id) + const differentAsset = ctx.any.application() + + const arc4Str1 = ctx.any.arc4.str(10) + const sameArc4Str = new StrImpl((arc4Str1 as StrImpl).typeInfo, arc4Str1.native) + const differentArc4Str = ctx.any.arc4.str(10) + + const testData = [ + { subject: '', test: '', expected: true }, + { subject: 'hello', test: 'hello', expected: true }, + { subject: 'hello', test: 'world', expected: false }, + { subject: '', test: 'world', expected: false }, + { subject: Bytes(), test: Bytes(), expected: true }, + { subject: Bytes('hello'), test: Bytes('hello'), expected: true }, + { subject: Bytes('hello'), test: Bytes('world'), expected: false }, + { subject: Bytes(''), test: Bytes('world'), expected: false }, + { subject: account1, test: account1, expected: true }, + { subject: account1, test: sameAccount, expected: true }, + { subject: account1, test: differentAccount, expected: false }, + { subject: app1, test: app1, expected: true }, + { subject: app1, test: sameApp, expected: true }, + { subject: app1, test: differentApp, expected: false }, + { subject: asset1, test: asset1, expected: true }, + { subject: asset1, test: sameAsset, expected: true }, + { subject: asset1, test: differentAsset, expected: false }, + { subject: arc4Str1, test: arc4Str1, expected: true }, + { subject: arc4Str1, test: sameArc4Str, expected: true }, + { subject: arc4Str1, test: differentArc4Str, expected: false }, + { subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { a: 'hello', b: { lessThanEq: 42 }, c: sameArc4Str }, expected: true }, + { subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { c: sameArc4Str }, expected: true }, + { subject: { a: 'hello', b: 42, c: arc4Str1 }, test: { c: differentArc4Str }, expected: false }, + { subject: ['hello', 42, arc4Str1], test: ['hello', { lessThanEq: 42 }, sameArc4Str], expected: true }, + { subject: ['hello', 42, arc4Str1], test: ['hello'], expected: true }, + { subject: ['hello', 42, arc4Str1], test: ['world'], expected: false }, + ] + + test.each(numericTestData)('should be able to match numeric data %s', (data) => { + const { subject, test, expected } = data + expect(match(subject, test)).toBe(expected) + }) + + test.each(testData)('should be able to match %s', (data) => { + const { subject, test, expected } = data + expect(match(subject, test)).toBe(expected) + }) + + test.each(numericTestData.filter((x) => x.expected))('should be able to assert match numeric data %s', (data) => { + const { subject, test, expected } = data + expect(assertMatch(subject, test)).toBe(expected) + }) + + test.each(testData.filter((x) => x.expected))('should be able to assert match %s', (data) => { + const { subject, test, expected } = data + expect(match(subject, test)).toBe(expected) + }) + + test.each(numericTestData.filter((x) => !x.expected))('should throw exception when assert match fails for numeric data %s', (data) => { + const { subject, test } = data + expect(() => assertMatch(subject, test)).toThrow('Assertion failed') + }) + + test.each(testData.filter((x) => !x.expected))('should throw exception when assert match fails %s', (data) => { + const { subject, test } = data + expect(() => assertMatch(subject, test)).toThrow('Assertion failed') + }) +}) diff --git a/tests/urange.spec.ts b/tests/urange.spec.ts new file mode 100644 index 0000000..f68d9ea --- /dev/null +++ b/tests/urange.spec.ts @@ -0,0 +1,57 @@ +import { Uint64, urange } from '@algorandfoundation/algorand-typescript' +import { describe, expect, it } from 'vitest' + +describe('urange', () => { + it('should iterate from 0 to a-1 when only a is provided', () => { + const a = Uint64(5) + const iterator = urange(a) + const result = [] + + for (let item = iterator.next(); !item.done; item = iterator.next()) { + result.push(item.value) + } + + expect(result).toEqual([BigInt(0), BigInt(1), BigInt(2), BigInt(3), BigInt(4)]) + }) + + it('should iterate from a to b-1 when a and b are provided', () => { + const a = Uint64(2) + const b = Uint64(5) + const iterator = urange(a, b) + const result = [] + + for (let item = iterator.next(); !item.done; item = iterator.next()) { + result.push(item.value) + } + + expect(result).toEqual([BigInt(2), BigInt(3), BigInt(4)]) + }) + + it('should iterate from a to b-1 with step c when a, b, and c are provided', () => { + const a = Uint64(2) + const b = Uint64(10) + const c = Uint64(2) + const iterator = urange(a, b, c) + const result = [] + + for (let item = iterator.next(); !item.done; item = iterator.next()) { + result.push(item.value) + } + + expect(result).toEqual([BigInt(2), BigInt(4), BigInt(6), BigInt(8)]) + }) + + it('should return iteration count when done', () => { + const a = Uint64(3) + const iterator = urange(a) + let item = iterator.next() + let count = 0 + + while (!item.done) { + count++ + item = iterator.next() + } + + expect(item.value).toBe(count) + }) +}) From 92ff82471c03d1888d20a7df5fb5df971231661b Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 30 Dec 2024 14:14:51 +0800 Subject: [PATCH 79/85] feat: add tests for auction example contract --- examples/auction/contract.spec.ts | 160 +++++++++++++++++++++++++ src/impl/inner-transactions.ts | 16 +-- src/runtime-helpers.ts | 13 ++ src/subcontexts/transaction-context.ts | 10 +- src/value-generators/avm.ts | 12 +- 5 files changed, 191 insertions(+), 20 deletions(-) create mode 100644 examples/auction/contract.spec.ts diff --git a/examples/auction/contract.spec.ts b/examples/auction/contract.spec.ts new file mode 100644 index 0000000..f1cc2e5 --- /dev/null +++ b/examples/auction/contract.spec.ts @@ -0,0 +1,160 @@ +import { TransactionType } from '@algorandfoundation/algorand-typescript' +import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { afterEach, describe, expect, it } from 'vitest' +import { Auction } from './contract.algo' + +describe('Auction', () => { + const ctx = new TestExecutionContext() + afterEach(() => { + ctx.reset() + }) + + it('should be able to opt into an asset', () => { + // Arrange + const asset = ctx.any.asset() + const contract = ctx.contract.create(Auction) + contract.createApplication() + + // Act + contract.optIntoAsset(asset) + + // Assert + expect(contract.asa.value.id).toEqual(asset.id) + const innerTxn = ctx.txn.lastGroup.lastItxnGroup().getAssetTransferInnerTxn() + + expect(innerTxn.assetReceiver, 'Asset receiver does not match').toEqual(ctx.ledger.getApplicationForContract(contract).address) + + expect(innerTxn.xferAsset, 'Transferred asset does not match').toEqual(asset) + }) + + it('should be able to start an auction', () => { + // Arrange + const contract = ctx.contract.create(Auction) + contract.createApplication() + + const app = ctx.ledger.getApplicationForContract(contract) + + const latestTimestamp = ctx.any.uint64(1, 1000) + const startingPrice = ctx.any.uint64() + const auctionDuration = ctx.any.uint64(100, 1000) + const axferTxn = ctx.any.txn.assetTransfer({ + assetReceiver: app.address, + assetAmount: startingPrice, + }) + contract.asaAmt.value = startingPrice + ctx.ledger.patchGlobalData({ + latestTimestamp: latestTimestamp, + }) + + // Act + contract.startAuction(startingPrice, auctionDuration, axferTxn) + + // Assert + expect(contract.auctionEnd.value).toEqual(latestTimestamp + auctionDuration) + expect(contract.previousBid.value).toEqual(startingPrice) + expect(contract.asaAmt.value).toEqual(startingPrice) + }) + + it('should be able to bid', () => { + // Arrange + const account = ctx.defaultSender + const auctionEnd = ctx.any.uint64(Date.now() + 10_000) + const previousBid = ctx.any.uint64(1, 100) + const payAmount = ctx.any.uint64() + + const contract = ctx.contract.create(Auction) + contract.createApplication() + contract.auctionEnd.value = auctionEnd + contract.previousBid.value = previousBid + const pay = ctx.any.txn.payment({ sender: account, amount: payAmount }) + + // Act + contract.bid(pay) + + // Assert + expect(contract.previousBid.value).toEqual(payAmount) + expect(contract.previousBidder.value).toEqual(account) + expect(contract.claimableAmount(account).value).toEqual(payAmount) + }) + + it('should be able to claim bids', () => { + // Arrange + const account = ctx.any.account() + const contract = ctx.contract.create(Auction) + contract.createApplication() + + const claimableAmount = ctx.any.uint64() + contract.claimableAmount(account).value = claimableAmount + + contract.previousBidder.value = account + const previousBid = ctx.any.uint64(undefined, claimableAmount) + contract.previousBid.value = previousBid + + // Act + ctx.txn.createScope([ctx.any.txn.applicationCall({ sender: account })]).execute(() => { + contract.claimBids() + }) + + // Assert + const expectedPayment = claimableAmount - previousBid + const lastInnerTxn = ctx.txn.lastGroup.lastItxnGroup().getPaymentInnerTxn() + + expect(lastInnerTxn.amount).toEqual(expectedPayment) + expect(lastInnerTxn.receiver).toEqual(account) + expect(contract.claimableAmount(account).value).toEqual(claimableAmount - expectedPayment) + }) + + it('should be able to claim asset', () => { + // Arrange + ctx.ledger.patchGlobalData({ latestTimestamp: ctx.any.uint64() }) + const contract = ctx.contract.create(Auction) + contract.createApplication() + + contract.auctionEnd.value = ctx.any.uint64(1, 100) + contract.previousBidder.value = ctx.defaultSender + const asaAmount = ctx.any.uint64(1000, 2000) + contract.asaAmt.value = asaAmount + const asset = ctx.any.asset() + + // Act + contract.claimAsset(asset) + + // Assert + const lastInnerTxn = ctx.txn.lastGroup.lastItxnGroup().getAssetTransferInnerTxn() + expect(lastInnerTxn.xferAsset).toEqual(asset) + expect(lastInnerTxn.assetCloseTo).toEqual(ctx.defaultSender) + expect(lastInnerTxn.assetReceiver).toEqual(ctx.defaultSender) + expect(lastInnerTxn.assetAmount).toEqual(asaAmount) + }) + + it('should be able to delete application', () => { + // Arrange + const account = ctx.any.account() + + // Act + // setting sender will determine creator + let contract + ctx.txn.createScope([ctx.any.txn.applicationCall({ sender: account })]).execute(() => { + contract = ctx.contract.create(Auction) + contract.createApplication() + }) + + ctx.txn.createScope([ctx.any.txn.applicationCall({ onCompletion: 'DeleteApplication' })]).execute(() => { + contract!.deleteApplication() + }) + + // Assert + const innerTransactions = ctx.txn.lastGroup.lastItxnGroup().getPaymentInnerTxn() + expect(innerTransactions).toBeTruthy() + expect(innerTransactions.type).toEqual(TransactionType.Payment) + expect(innerTransactions.receiver).toEqual(account) + expect(innerTransactions.closeRemainderTo).toEqual(account) + }) + + it('should be able to call clear state program', () => { + const contract = ctx.contract.create(Auction) + contract.createApplication() + + expect(contract.clearStateProgram()).toBeTruthy() + }) +}) diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts index b2ec556..82d7903 100644 --- a/src/impl/inner-transactions.ts +++ b/src/impl/inner-transactions.ts @@ -191,27 +191,21 @@ export function submitGroup(...transactionFie return transactionFields.map((f: (typeof transactionFields)[number]) => f.submit()) as itxn.TxnFor } export function payment(fields: itxn.PaymentFields): itxn.PaymentItxnParams { - ensureItxnGroupBegin() return new ItxnParams(fields, TransactionType.Payment) } export function keyRegistration(fields: itxn.KeyRegistrationFields): itxn.KeyRegistrationItxnParams { - ensureItxnGroupBegin() return new ItxnParams(fields, TransactionType.KeyRegistration) } export function assetConfig(fields: itxn.AssetConfigFields): itxn.AssetConfigItxnParams { - ensureItxnGroupBegin() return new ItxnParams(fields, TransactionType.AssetConfig) } export function assetTransfer(fields: itxn.AssetTransferFields): itxn.AssetTransferItxnParams { - ensureItxnGroupBegin() return new ItxnParams(fields, TransactionType.AssetTransfer) } export function assetFreeze(fields: itxn.AssetFreezeFields): itxn.AssetFreezeItxnParams { - ensureItxnGroupBegin() return new ItxnParams(fields, TransactionType.AssetFreeze) } export function applicationCall(fields: itxn.ApplicationCallFields): itxn.ApplicationCallItxnParams { - ensureItxnGroupBegin() return new ItxnParams(fields, TransactionType.ApplicationCall) } @@ -221,7 +215,9 @@ export class ItxnParams(this.#fields) as unknown as TTransaction + const innerTxn = createInnerTxn(this.#fields) as unknown as TTransaction + lazyContext.txn.activeGroup.addInnerTransactionGroup(innerTxn) + return innerTxn } set(p: Partial) { @@ -232,9 +228,3 @@ export class ItxnParams(this.#fields, this.#fields.type) } } - -const ensureItxnGroupBegin = () => { - if (!lazyContext.activeGroup.constructingItxnGroup.length) { - lazyContext.activeGroup.beginInnerTransactionGroup() - } -} diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 2edd1b5..3acfb03 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -3,6 +3,7 @@ import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' import { MAX_UINT64 } from './constants' import type { TypeInfo } from './encoders' import { AccountCls } from './impl/account' +import { Uint64BackedCls } from './impl/base' import { DeliberateAny } from './typescript-helpers' import { nameOfType } from './util' @@ -48,6 +49,9 @@ export function binaryOp(left: unknown, right: unknown, op: BinaryOps) { if (left instanceof AccountCls && right instanceof AccountCls) { return accountBinaryOp(left, right, op) } + if (left instanceof Uint64BackedCls && right instanceof Uint64BackedCls) { + return uint64BackedClsBinaryOp(left, right, op) + } if (left instanceof internal.primitives.BigUintCls || right instanceof internal.primitives.BigUintCls) { return bigUintBinaryOp(left, right, op) } @@ -105,6 +109,15 @@ function accountBinaryOp(left: AccountCls, right: AccountCls, op: BinaryOps): De internal.errors.internalError(`Unsupported operator ${op}`) } } +function uint64BackedClsBinaryOp(left: Uint64BackedCls, right: Uint64BackedCls, op: BinaryOps): DeliberateAny { + switch (op) { + case '===': + case '!==': + return uint64BinaryOp(left.uint64, right.uint64, op) + default: + internal.errors.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() diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 04e1863..78ad364 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -88,14 +88,14 @@ export class TransactionContext { createScope(group: Array>, activeTransactionIndex?: number): ExecutionScope { const transactions = group.map((t) => (t instanceof DeferredAppCall ? t.txns : [t])).flat() const transactionGroup = new TransactionGroup(transactions, activeTransactionIndex) - const previousGroup = this.#activeGroup + this.#activeGroup = transactionGroup const scope = ScopeGenerator(() => { if (this.#activeGroup?.transactions?.length) { this.groups.push(this.#activeGroup) } - this.#activeGroup = previousGroup + this.#activeGroup = undefined }) return { execute: (body: () => TReturn) => { @@ -221,6 +221,9 @@ export class TransactionGroup { Object.assign(activeTransaction, filteredFields) } + addInnerTransactionGroup(...itxns: InnerTxn[]) { + this.itxnGroups.push(new ItxnGroup(itxns)) + } beginInnerTransactionGroup() { if (this.constructingItxnGroup.length) { internal.errors.internalError('itxn begin without itxn submit') @@ -252,6 +255,9 @@ export class TransactionGroup { this.constructingItxnGroup = [] } + lastItxnGroup() { + return this.getItxnGroup() + } getItxnGroup(index?: internal.primitives.StubUint64Compat): ItxnGroup { const i = index !== undefined ? asNumber(index) : undefined diff --git a/src/value-generators/avm.ts b/src/value-generators/avm.ts index a79ec08..d651edb 100644 --- a/src/value-generators/avm.ts +++ b/src/value-generators/avm.ts @@ -18,17 +18,19 @@ type AssetContextData = Partial & { assetId?: internal.primitives.Stu type ApplicationContextData = Partial & { applicationId?: internal.primitives.StubUint64Compat } export class AvmValueGenerator { - uint64(minValue: number | bigint = 0n, maxValue: number | bigint = MAX_UINT64): uint64 { - if (maxValue > MAX_UINT64) { + uint64(minValue: internal.primitives.StubUint64Compat = 0n, maxValue: internal.primitives.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') } - if (minValue > maxValue) { + if (min > max) { internal.errors.internalError('minValue must be less than or equal to maxValue') } - if (minValue < 0n || maxValue < 0n) { + if (min < 0n || max < 0n) { internal.errors.internalError('minValue and maxValue must be greater than or equal to 0') } - return Uint64(getRandomBigInt(minValue, maxValue)) + return Uint64(getRandomBigInt(min, max)) } bytes(length = MAX_BYTES_SIZE): bytes { From 3b2a05db2d5921878da4a05e64b22c181e684472 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Mon, 30 Dec 2024 17:30:04 +0800 Subject: [PATCH 80/85] feat: add tests for voting example contract --- examples/hello-world-abi/contract.spec.ts | 7 +- examples/htlc-logicsig/signature.spec.ts | 4 +- examples/precompiled/contract.spec.ts | 9 ++- examples/voting/contract.algo.ts | 2 +- examples/voting/contract.spec.ts | 96 +++++++++++++++++++++++ src/decode-logs.ts | 13 ++- src/encoders.ts | 35 ++++++++- src/impl/app-global.ts | 3 +- src/impl/app-local.ts | 3 +- src/impl/box.ts | 3 +- src/impl/inner-transactions.ts | 17 ++-- src/impl/match.ts | 10 +-- src/impl/state.ts | 4 +- src/impl/transactions.ts | 12 +-- src/index.ts | 1 + src/runtime-helpers.ts | 2 +- src/subcontexts/contract-context.ts | 3 +- src/util.ts | 32 -------- src/value-generators/avm.ts | 9 +++ tests/references/box-map.spec.ts | 3 +- tests/references/box.spec.ts | 3 +- 21 files changed, 190 insertions(+), 81 deletions(-) create mode 100644 examples/voting/contract.spec.ts diff --git a/examples/hello-world-abi/contract.spec.ts b/examples/hello-world-abi/contract.spec.ts index 55e85b9..32de4fe 100644 --- a/examples/hello-world-abi/contract.spec.ts +++ b/examples/hello-world-abi/contract.spec.ts @@ -1,7 +1,6 @@ import { assert, Bytes, TransactionType } 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 HelloWorldContract from './contract.algo' describe('HelloWorldContract', () => { @@ -16,9 +15,8 @@ describe('HelloWorldContract', () => { expect(result).toBe('Bananas') const bananasBytes = Bytes('Bananas') - const abiLog = ABI_RETURN_VALUE_LOG_PREFIX.concat(bananasBytes) const logs = ctx.exportLogs(ctx.txn.lastActive.appId.id, 's', 'b') - expect(logs).toStrictEqual([result, abiLog]) + expect(logs).toStrictEqual([result, bananasBytes]) }) it('logs the returned value when sayHello is called', async () => { const contract = ctx.contract.create(HelloWorldContract) @@ -27,8 +25,7 @@ describe('HelloWorldContract', () => { expect(result).toBe('Hello John Doe') const helloBytes = Bytes('Hello John Doe') - const abiLog = ABI_RETURN_VALUE_LOG_PREFIX.concat(helloBytes) const logs = ctx.exportLogs(ctx.txn.lastActive.appId.id, 's', 'b') - expect(logs).toStrictEqual([result, abiLog]) + expect(logs).toStrictEqual([result, helloBytes]) }) }) diff --git a/examples/htlc-logicsig/signature.spec.ts b/examples/htlc-logicsig/signature.spec.ts index 2224f10..c9cab8f 100644 --- a/examples/htlc-logicsig/signature.spec.ts +++ b/examples/htlc-logicsig/signature.spec.ts @@ -2,9 +2,11 @@ import { Account, Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import algosdk from 'algosdk' import { afterEach, describe, expect, it } from 'vitest' -import { ZERO_ADDRESS } from '../../src/constants' import HashedTimeLockedLogicSig from './signature.algo' +const ZERO_ADDRESS_B32 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ' +const ZERO_ADDRESS = Bytes.fromBase32(ZERO_ADDRESS_B32) + describe('HTLC LogicSig', () => { const ctx = new TestExecutionContext() diff --git a/examples/precompiled/contract.spec.ts b/examples/precompiled/contract.spec.ts index 5f85484..88cf330 100644 --- a/examples/precompiled/contract.spec.ts +++ b/examples/precompiled/contract.spec.ts @@ -1,11 +1,12 @@ -import { arc4 } from '@algorandfoundation/algorand-typescript' +import { arc4, Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' import { afterEach, describe, it } from 'vitest' -import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_BYTES_SIZE } from '../../src/constants' -import { asUint64Cls } from '../../src/util' import { HelloFactory } from './contract.algo' import { Hello, HelloTemplate, HelloTemplateCustomPrefix, LargeProgram, TerribleCustodialAccount } from './precompiled-apps.algo' +const MAX_BYTES_SIZE = 4096 +const ABI_RETURN_VALUE_LOG_PREFIX = Bytes.fromHex('151F7C75') + describe('pre compiled app calls', () => { const ctx = new TestExecutionContext() afterEach(() => { @@ -58,7 +59,7 @@ describe('pre compiled app calls', () => { // Arrange const largeProgramApp = ctx.any.application({ approvalProgram: ctx.any.bytes(20), - appLogs: [ABI_RETURN_VALUE_LOG_PREFIX.concat(asUint64Cls(MAX_BYTES_SIZE).toBytes().asAlgoTs())], + appLogs: [ABI_RETURN_VALUE_LOG_PREFIX.concat(Bytes(MAX_BYTES_SIZE))], }) ctx.setCompiledApp(LargeProgram, largeProgramApp.id) diff --git a/examples/voting/contract.algo.ts b/examples/voting/contract.algo.ts index 53a43e3..734f50d 100644 --- a/examples/voting/contract.algo.ts +++ b/examples/voting/contract.algo.ts @@ -154,7 +154,7 @@ export class VotingRoundApp extends arc4.Contract { note: note, fee: Global.minTxnFee, }) - .submit().configAsset + .submit().createdAsset } @abimethod({ readonly: true }) diff --git a/examples/voting/contract.spec.ts b/examples/voting/contract.spec.ts new file mode 100644 index 0000000..c1c59c8 --- /dev/null +++ b/examples/voting/contract.spec.ts @@ -0,0 +1,96 @@ +import { Bytes, Uint64 } from '@algorandfoundation/algorand-typescript' +import { bytesToUint8Array, TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { DynamicArray, UintN8 } from '@algorandfoundation/algorand-typescript/arc4' +import nacl from 'tweetnacl' +import { afterEach, describe, expect, it } from 'vitest' +import { VotingRoundApp } from './contract.algo' + +describe('VotingRoundApp', () => { + const ctx = new TestExecutionContext() + + const boostrapMinBalanceReq = Uint64(287100) + const voteMinBalanceReq = Uint64(21300) + const tallyBoxSize = 208 + const keyPair = nacl.sign.keyPair() + const voteId = ctx.any.string() + + const createContract = () => { + const contract = ctx.contract.create(VotingRoundApp) + const snapshotPublicKey = Bytes(keyPair.publicKey) + const metadataIpfsCid = ctx.any.string(16) + const startTime = ctx.any.uint64(Date.now() - 10_000, Date.now()) + const endTime = ctx.any.uint64(Date.now() + 10_000, Date.now() + 100_000) + const optionCounts = new DynamicArray( + ...Array(13) + .fill(0) + .map(() => new UintN8(2)), + ) + const quorum = ctx.any.uint64() + const nftImageUrl = ctx.any.string(64) + contract.create(voteId, snapshotPublicKey, metadataIpfsCid, startTime, endTime, optionCounts, quorum, nftImageUrl) + return contract + } + + afterEach(() => { + ctx.reset() + }) + + it('shoulld be able to bootstrap', () => { + const contract = createContract() + const app = ctx.ledger.getApplicationForContract(contract) + contract.bootstrap(ctx.any.txn.payment({ receiver: app.address, amount: boostrapMinBalanceReq })) + + expect(contract.isBootstrapped.value).toEqual(true) + expect(contract.tallyBox.value).toEqual(Bytes.fromHex('00'.repeat(tallyBoxSize))) + }) + + it('should be able to get pre conditions', () => { + const contract = createContract() + const app = ctx.ledger.getApplicationForContract(contract) + contract.bootstrap(ctx.any.txn.payment({ receiver: app.address, amount: boostrapMinBalanceReq })) + + const account = ctx.any.account() + const signature = nacl.sign.detached(bytesToUint8Array(account.bytes), keyPair.secretKey) + ctx.txn.createScope([ctx.any.txn.applicationCall({ sender: account })]).execute(() => { + const preconditions = contract.getPreconditions(Bytes(signature)) + + expect(preconditions.is_allowed_to_vote).toEqual(1) + expect(preconditions.is_voting_open).toEqual(1) + expect(preconditions.has_already_voted).toEqual(0) + expect(preconditions.current_time).toEqual(ctx.txn.activeGroup.latestTimestamp) + }) + }) + + it('should be able to vote', () => { + const contract = createContract() + const app = ctx.ledger.getApplicationForContract(contract) + contract.bootstrap(ctx.any.txn.payment({ receiver: app.address, amount: boostrapMinBalanceReq })) + + const account = ctx.any.account() + const signature = nacl.sign.detached(bytesToUint8Array(account.bytes), keyPair.secretKey) + const answerIds = new DynamicArray( + ...Array(13) + .fill(0) + .map(() => new UintN8(Math.ceil(Math.random() * 10) % 2)), + ) + + 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.voterCount.value).toEqual(13) + }) + }) + + it('should be able to close', () => { + const contract = createContract() + const app = ctx.ledger.getApplicationForContract(contract) + contract.bootstrap(ctx.any.txn.payment({ receiver: app.address, amount: boostrapMinBalanceReq })) + + contract.close() + + expect(contract.closeTime.value).toEqual(ctx.txn.lastGroup.latestTimestamp) + expect(contract.nftAsset.value.name).toEqual(`[VOTE RESULT] ${voteId}`) + expect(contract.nftAsset.value.unitName).toEqual('VOTERSLT') + }) +}) diff --git a/src/decode-logs.ts b/src/decode-logs.ts index 2fa74f0..e020a27 100644 --- a/src/decode-logs.ts +++ b/src/decode-logs.ts @@ -1,4 +1,6 @@ import { bytes, op } from '@algorandfoundation/algorand-typescript' +import { ABI_RETURN_VALUE_LOG_PREFIX } from './constants' +import { asNumber } from './util' export type LogDecoding = 'i' | 's' | 'b' @@ -6,15 +8,20 @@ export type DecodedLog = T extends 'i' ? bigint : T exten export type DecodedLogs = { [Index in keyof T]: DecodedLog } & { length: T['length'] } + +const ABI_RETURN_VALUE_LOG_PREFIX_LENGTH = asNumber(ABI_RETURN_VALUE_LOG_PREFIX.length) export function decodeLogs(logs: bytes[], decoding: T): DecodedLogs { return logs.map((log, i) => { + const value = log.slice(0, ABI_RETURN_VALUE_LOG_PREFIX_LENGTH).equals(ABI_RETURN_VALUE_LOG_PREFIX) + ? log.slice(ABI_RETURN_VALUE_LOG_PREFIX_LENGTH) + : log switch (decoding[i]) { case 'i': - return op.btoi(log) + return op.btoi(value) case 's': - return log.toString() + return value.toString() default: - return log + return value } }) as DecodedLogs } diff --git a/src/encoders.ts b/src/encoders.ts index be9c12c..2cf964c 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 { OnCompleteAction } from '@algorandfoundation/algorand-typescript/arc4' +import { ARC4Encoded, OnCompleteAction } from '@algorandfoundation/algorand-typescript/arc4' import { AccountCls } from './impl/account' import { ApplicationCls } from './impl/application' import { AssetCls } from './impl/asset' -import { arc4Encoders, getArc4Encoder } from './impl/encoded-types' +import { BytesBackedCls, Uint64BackedCls } from './impl/base' +import { arc4Encoders, encodeArc4Impl, getArc4Encoder } from './impl/encoded-types' import { DeliberateAny } from './typescript-helpers' -import { asBytes, asUint8Array } from './util' +import { asBytes, asMaybeBigUintCls, asMaybeBytesCls, asMaybeUint64Cls, asUint64Cls, asUint8Array, nameOfType } from './util' export type TypeInfo = { name: string @@ -59,3 +60,31 @@ export const encoders: Record> = { export const getEncoder = (typeInfo: TypeInfo): fromBytes => { return getArc4Encoder(typeInfo, encoders) } + +export const toBytes = (val: unknown): bytes => { + const uint64Val = asMaybeUint64Cls(val) + if (uint64Val !== undefined) { + return uint64Val.toBytes().asAlgoTs() + } + const bytesVal = asMaybeBytesCls(val) + if (bytesVal !== undefined) { + return bytesVal.asAlgoTs() + } + const bigUintVal = asMaybeBigUintCls(val) + if (bigUintVal !== undefined) { + return bigUintVal.toBytes().asAlgoTs() + } + if (val instanceof BytesBackedCls) { + return val.bytes + } + if (val instanceof Uint64BackedCls) { + return asUint64Cls(val.uint64).toBytes().asAlgoTs() + } + if (val instanceof ARC4Encoded) { + return val.bytes + } + if (Array.isArray(val) || typeof val === 'object') { + return encodeArc4Impl('', val) + } + internal.errors.internalError(`Invalid type for bytes: ${nameOfType(val)}`) +} diff --git a/src/impl/app-global.ts b/src/impl/app-global.ts index eaa5470..6d04bb7 100644 --- a/src/impl/app-global.ts +++ b/src/impl/app-global.ts @@ -1,6 +1,7 @@ import { Application, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes, toBytes } from '../util' +import { toBytes } from '../encoders' +import { asBytes } from '../util' import { getApp } from './app-params' export const AppGlobal: internal.opTypes.AppGlobalType = { diff --git a/src/impl/app-local.ts b/src/impl/app-local.ts index d6feb16..c8329f6 100644 --- a/src/impl/app-local.ts +++ b/src/impl/app-local.ts @@ -1,6 +1,7 @@ import { Account, Application, Bytes, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes, toBytes } from '../util' +import { toBytes } from '../encoders' +import { asBytes } from '../util' import { getAccount } from './acct-params' import { getApp } from './app-params' diff --git a/src/impl/box.ts b/src/impl/box.ts index c1bdf84..a7ffabe 100644 --- a/src/impl/box.ts +++ b/src/impl/box.ts @@ -1,7 +1,8 @@ import { bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays, toBytes } from '../util' +import { toBytes } from '../encoders' +import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays } from '../util' export const Box: internal.opTypes.BoxType = { create(a: internal.primitives.StubBytesCompat, b: internal.primitives.StubUint64Compat): boolean { diff --git a/src/impl/inner-transactions.ts b/src/impl/inner-transactions.ts index 82d7903..7ebe59f 100644 --- a/src/impl/inner-transactions.ts +++ b/src/impl/inner-transactions.ts @@ -1,7 +1,7 @@ import { Account, Application, arc4, Asset, bytes, internal, itxn, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' import { Mutable } from '../typescript-helpers' -import { asBytes } from '../util' +import { asBytes, asNumber } from '../util' import { getApp } from './app-params' import { getAsset } from './asset-params' import { InnerTxn, InnerTxnFields } from './itxn' @@ -66,12 +66,15 @@ export class AssetConfigInnerTxn extends AssetConfigTransaction implements itxn. /* @internal */ constructor(fields: itxn.AssetConfigFields) { const { assetName, unitName, url, ...rest } = mapCommonFields(fields) - const createdAsset = lazyContext.any.asset({ - name: typeof assetName === 'string' ? asBytes(assetName) : assetName, - unitName: typeof unitName === 'string' ? asBytes(unitName) : unitName, - url: typeof url === 'string' ? asBytes(url) : url, - ...rest, - }) + const createdAsset = + !rest.configAsset || !asNumber(rest.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, + ...rest, + }) + : undefined super({ assetName: typeof assetName === 'string' ? asBytes(assetName) : assetName, diff --git a/src/impl/match.ts b/src/impl/match.ts index da87e3f..2ef59c6 100644 --- a/src/impl/match.ts +++ b/src/impl/match.ts @@ -33,11 +33,11 @@ export const matchImpl: typeof match = (subject, test): boolean => { getBigIntValue(subject.uint64 as unknown as internal.primitives.Uint64Cls) === getBigIntValue((test as unknown as Uint64BackedCls).uint64 as unknown as internal.primitives.Uint64Cls) ) - } else if (subject instanceof ARC4Encoded) { - return subject.bytes.equals((test as unknown as ARC4Encoded).bytes) - } else if (Array.isArray(subject)) { - return (test as []).map((x, i) => matchImpl((subject as DeliberateAny)[i], x as DeliberateAny)).every((x) => x) - } else if (typeof subject === 'object') { + } else if (test instanceof ARC4Encoded) { + return (subject as unknown as ARC4Encoded).bytes.equals(test.bytes) + } else if (Array.isArray(test)) { + return test.map((x, i) => matchImpl((subject as DeliberateAny)[i], x as DeliberateAny)).every((x) => x) + } else if (typeof test === 'object') { return Object.entries(test!) .map(([k, v]) => matchImpl((subject as DeliberateAny)[k], v as DeliberateAny)) .every((x) => x) diff --git a/src/impl/state.ts b/src/impl/state.ts index 2382644..2f14e79 100644 --- a/src/impl/state.ts +++ b/src/impl/state.ts @@ -17,9 +17,9 @@ import { import { AccountMap } from '../collections/custom-key-map' import { MAX_BOX_SIZE } from '../constants' import { lazyContext } from '../context-helpers/internal-context' -import { getEncoder, TypeInfo } from '../encoders' +import { getEncoder, toBytes, TypeInfo } from '../encoders' import { getGenericTypeInfo } from '../runtime-helpers' -import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays, toBytes } from '../util' +import { asBytes, asBytesCls, asNumber, asUint8Array, conactUint8Arrays } from '../util' export class GlobalStateCls { private readonly _type: string = GlobalStateCls.name diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index fda0abd..d2d7573 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -13,17 +13,9 @@ import { } 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 { - asBytes, - asMaybeBytesCls, - asMaybeUint64Cls, - asNumber, - asUint64Cls, - combineIntoMaxBytePages, - getRandomBytes, - toBytes, -} from '../util' +import { asBytes, asMaybeBytesCls, asMaybeUint64Cls, asNumber, asUint64Cls, combineIntoMaxBytePages, getRandomBytes } from '../util' const baseDefaultFields = () => ({ sender: lazyContext.defaultSender, diff --git a/src/index.ts b/src/index.ts index 9d9b0b8..26df64c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ export { TestExecutionContext } from './test-execution-context' +export { asUint8Array as bytesToUint8Array } from './util' diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index 3acfb03..3d7c5bf 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -36,7 +36,7 @@ type UnaryOps = '~' function tryGetBigInt(value: unknown): bigint | undefined { if (typeof value == 'bigint') return value - if (typeof value == 'number') return BigInt(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() return undefined diff --git a/src/subcontexts/contract-context.ts b/src/subcontexts/contract-context.ts index 7f60248..4603e5b 100644 --- a/src/subcontexts/contract-context.ts +++ b/src/subcontexts/contract-context.ts @@ -21,7 +21,7 @@ import { import { BytesMap } from '../collections/custom-key-map' import { checkRoutingConditions } from '../context-helpers/context-util' import { lazyContext } from '../context-helpers/internal-context' -import type { TypeInfo } from '../encoders' +import { toBytes, type TypeInfo } from '../encoders' import { AccountCls } from '../impl/account' import { ApplicationCls } from '../impl/application' import { AssetCls } from '../impl/asset' @@ -37,7 +37,6 @@ import { } from '../impl/transactions' import { getGenericTypeInfo } from '../runtime-helpers' import { DeliberateAny, IConstructor } from '../typescript-helpers' -import { toBytes } from '../util' type ContractOptionsParameter = Parameters[0] diff --git a/src/util.ts b/src/util.ts index ff0ec08..c139cd8 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,5 +1,4 @@ import { Account, Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' -import { ARC4Encoded } from '@algorandfoundation/algorand-typescript/arc4' import { encodingUtil } from '@algorandfoundation/puya-ts' import { randomBytes } from 'crypto' import { sha512_256 as js_sha512_256 } from 'js-sha512' @@ -15,7 +14,6 @@ import { MAX_UINT8, UINT512_SIZE, } from './constants' -import { BytesBackedCls, Uint64BackedCls } from './impl/base' import { DeliberateAny } from './typescript-helpers' export const nameOfType = (x: unknown) => { @@ -59,36 +57,6 @@ export const asBytes = (val: internal.primitives.StubBytesCompat | Uint8Array) = export const asUint8Array = (val: internal.primitives.StubBytesCompat | Uint8Array) => asBytesCls(val).asUint8Array() -export const toBytes = (val: unknown): bytes => { - const uint64Val = asMaybeUint64Cls(val) - if (uint64Val !== undefined) { - return uint64Val.toBytes().asAlgoTs() - } - const bytesVal = asMaybeBytesCls(val) - if (bytesVal !== undefined) { - return bytesVal.asAlgoTs() - } - const bigUintVal = asMaybeBigUintCls(val) - if (bigUintVal !== undefined) { - return bigUintVal.toBytes().asAlgoTs() - } - if (val instanceof BytesBackedCls) { - return val.bytes - } - if (val instanceof Uint64BackedCls) { - return asUint64Cls(val.uint64).toBytes().asAlgoTs() - } - if (Array.isArray(val)) { - return val.reduce((acc: bytes, cur: unknown) => { - return acc.concat(toBytes(cur)) - }, Bytes()) - } - if (val instanceof ARC4Encoded) { - return val.bytes - } - internal.errors.internalError(`Invalid type for bytes: ${nameOfType(val)}`) -} - export const asMaybeUint64Cls = (val: DeliberateAny) => { try { return internal.primitives.Uint64Cls.fromCompat(val) diff --git a/src/value-generators/avm.ts b/src/value-generators/avm.ts index d651edb..a3cca0f 100644 --- a/src/value-generators/avm.ts +++ b/src/value-generators/avm.ts @@ -37,6 +37,15 @@ export class AvmValueGenerator { return Bytes(new Uint8Array(randomBytes(length))) } + string(length = 11): string { + const setLength = 11 + return Array(Math.ceil(length / setLength)) + .fill(0) + .map(() => Math.random().toString(36).substring(2)) + .join('') + .substring(0, length) + } + account(input?: AccountContextData): Account { const account = input?.address ?? Account(getRandomBytes(32).asAlgoTs()) diff --git a/tests/references/box-map.spec.ts b/tests/references/box-map.spec.ts index 82bbed2..d6d379e 100644 --- a/tests/references/box-map.spec.ts +++ b/tests/references/box-map.spec.ts @@ -3,8 +3,9 @@ import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-te import { ARC4Encoded, DynamicArray, interpretAsArc4, Str, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' import { afterEach, describe, expect, test } from 'vitest' import { MAX_UINT64 } from '../../src/constants' +import { toBytes } from '../../src/encoders' import { DeliberateAny } from '../../src/typescript-helpers' -import { asBytes, toBytes } from '../../src/util' +import { asBytes } from '../../src/util' const BOX_NOT_CREATED_ERROR = 'Box has not been created' diff --git a/tests/references/box.spec.ts b/tests/references/box.spec.ts index c64894a..9893344 100644 --- a/tests/references/box.spec.ts +++ b/tests/references/box.spec.ts @@ -3,8 +3,9 @@ import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-te 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 { asBytes, toBytes } from '../../src/util' +import { asBytes } from '../../src/util' import { BoxContract } from '../artifacts/box-contract/contract.algo' const BOX_NOT_CREATED_ERROR = 'Box has not been created' From 45203c2ac5bd041f1b9b0a75ff11c0fb21ff6d02 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 2 Jan 2025 14:02:14 +0800 Subject: [PATCH 81/85] refactor: hide internal members from consumers of testing package --- examples/voting/contract.spec.ts | 6 +++--- src/index.ts | 7 ++++++- src/subcontexts/ledger-context.ts | 1 + src/subcontexts/transaction-context.ts | 25 ++++++++----------------- src/test-execution-context.ts | 10 ++++++++++ tsconfig.build.json | 5 +++-- 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/examples/voting/contract.spec.ts b/examples/voting/contract.spec.ts index c1c59c8..96d09bb 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 { bytesToUint8Array, TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' +import { encodingUtil, TestExecutionContext } 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(bytesToUint8Array(account.bytes), keyPair.secretKey) + const signature = nacl.sign.detached(encodingUtil.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(bytesToUint8Array(account.bytes), keyPair.secretKey) + const signature = nacl.sign.detached(encodingUtil.toExternalValue(account.bytes), keyPair.secretKey) const answerIds = new DynamicArray( ...Array(13) .fill(0) diff --git a/src/index.ts b/src/index.ts index 26df64c..9ff217f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,7 @@ +import { internal } from '@algorandfoundation/algorand-typescript' + export { TestExecutionContext } from './test-execution-context' -export { asUint8Array as bytesToUint8Array } from './util' +export const encodingUtil = { + ...internal.encodingUtil, + toExternalValue: internal.primitives.toExternalValue, +} diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index 9062a48..1a1b0e0 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -23,6 +23,7 @@ export class LedgerContext { blocks = new Uint64Map() globalData = new GlobalData() + /* @internal */ addAppIdContractMap(appId: internal.primitives.StubUint64Compat, contract: BaseContract): void { this.appIdContractMap.set(appId, contract) } diff --git a/src/subcontexts/transaction-context.ts b/src/subcontexts/transaction-context.ts index 78ad364..3b9a119 100644 --- a/src/subcontexts/transaction-context.ts +++ b/src/subcontexts/transaction-context.ts @@ -1,6 +1,7 @@ import { bytes, Contract, internal, TransactionType, uint64 } from '@algorandfoundation/algorand-typescript' import { AbiMetadata, getContractMethodAbiMetadata } 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' @@ -49,23 +50,6 @@ interface ExecutionScope { execute: (body: () => TReturn) => TReturn } -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') - } - if (!isCreating && metadata.onCreate === 'require') { - throw new internal.errors.CodeError('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(', ')}`, - ) - } -} - export class DeferredAppCall { constructor( private readonly appId: uint64, @@ -106,6 +90,7 @@ export class TransactionContext { } } + /* internal */ ensureScope(group: Transaction[], activeTransactionIndex?: number): ExecutionScope { if (!this.#activeGroup || !this.#activeGroup.transactions.length) { return this.createScope(group, activeTransactionIndex) @@ -200,6 +185,7 @@ export class TransactionGroup { return this.activeTransaction.appId.id } + /* internal */ get constructingItxn() { if (!this.constructingItxnGroup.length) { internal.errors.internalError('itxn field without itxn begin') @@ -221,9 +207,12 @@ export class TransactionGroup { Object.assign(activeTransaction, filteredFields) } + /* internal */ addInnerTransactionGroup(...itxns: InnerTxn[]) { this.itxnGroups.push(new ItxnGroup(itxns)) } + + /* internal */ beginInnerTransactionGroup() { if (this.constructingItxnGroup.length) { internal.errors.internalError('itxn begin without itxn submit') @@ -235,6 +224,7 @@ export class TransactionGroup { this.constructingItxnGroup.push({} as InnerTxnFields) } + /* internal */ appendInnerTransactionGroup() { if (!this.constructingItxnGroup.length) { internal.errors.internalError('itxn next without itxn begin') @@ -242,6 +232,7 @@ export class TransactionGroup { this.constructingItxnGroup.push({ type: TransactionType.Payment } as InnerTxnFields) } + /* internal */ submitInnerTransactionGroup() { if (!this.constructingItxnGroup.length) { internal.errors.internalError('itxn submit without itxn begin') diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index af618ef..aed2937 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -44,26 +44,32 @@ export class TestExecutionContext implements internal.ExecutionContext { 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) } + /* @internal */ exportLogs(appId: uint64, ...decoding: T): DecodedLogs { return this.txn.exportLogs(appId, ...decoding) } + /* @internal */ get op() { return ops } @@ -87,12 +93,14 @@ export class TestExecutionContext implements internal.ExecutionContext { return this.#defaultSender } + /* @internal */ get abiMetadata() { return { captureMethodConfig, } } + /* @internal */ get gtxn() { return { Transaction: (index: uint64) => this.txn.activeGroup.getTransaction(index), @@ -105,6 +113,7 @@ export class TestExecutionContext implements internal.ExecutionContext { } } + /* @internal */ get itxn() { return { submitGroup: itxnSubmitGroup, @@ -117,6 +126,7 @@ export class TestExecutionContext implements internal.ExecutionContext { } } + /* @internal */ get state() { return { GlobalState, diff --git a/tsconfig.build.json b/tsconfig.build.json index a491539..d16304a 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -3,8 +3,9 @@ "compilerOptions": { "outDir": "./dist/", "noEmit": false, - "declaration": true + "declaration": true, + "stripInternal": true }, "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts", "src/**/tests/**", "examples/**/*.ts",] + "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts", "src/**/tests/**", "examples/**/*.ts"] } From 6d05031024c5a4937dfb820e7402de1370efedba Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Thu, 2 Jan 2025 17:56:22 +0800 Subject: [PATCH 82/85] refactor: capture generic type info only for boxes, global states, and local states as type info is not needed for others --- src/test-execution-context.ts | 1 - src/test-transformer/node-factory.ts | 10 ++++------ src/test-transformer/visitors.ts | 26 ++++++++++++++++++-------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/test-execution-context.ts b/src/test-execution-context.ts index aed2937..2ab676c 100644 --- a/src/test-execution-context.ts +++ b/src/test-execution-context.ts @@ -64,7 +64,6 @@ export class TestExecutionContext implements internal.ExecutionContext { this.txn.appendLog(value) } - /* @internal */ exportLogs(appId: uint64, ...decoding: T): DecodedLogs { return this.txn.exportLogs(appId, ...decoding) } diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index faec9ad..4014221 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -94,19 +94,17 @@ export const nodeFactory = { ) }, - callStubbedFunction(functionName: string, node: ts.CallExpression, ...typeInfos: (TypeInfo | undefined)[]) { - const infoStringArray = typeInfos.length ? typeInfos.map((typeInfo) => JSON.stringify(typeInfo)) : undefined + callStubbedFunction(functionName: string, node: ts.CallExpression, typeInfo?: TypeInfo) { + const typeInfoArg = typeInfo ? factory.createStringLiteral(JSON.stringify(typeInfo)) : undefined const updatedPropertyAccessExpression = factory.createPropertyAccessExpression( factory.createIdentifier('runtimeHelpers'), `${functionName}Impl`, ) - const typeInfoArgs = infoStringArray - ? infoStringArray?.filter((s) => !!s).map((infoString) => factory.createStringLiteral(infoString)) - : undefined + return factory.createCallExpression( updatedPropertyAccessExpression, node.typeArguments, - [...(typeInfoArgs ?? []), ...(node.arguments ?? [])].filter((arg) => !!arg), + [typeInfoArg, ...(node.arguments ?? [])].filter((arg) => !!arg), ) }, } satisfies Record ts.Node> diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index 8c69489..d4571b2 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -90,6 +90,7 @@ class ExpressionVisitor { private context: ts.TransformationContext, private helper: VisitorHelper, private expressionNode: ts.Expression, + private stubbedFunctionName?: string, ) {} public result(): ts.Expression { @@ -104,6 +105,7 @@ class ExpressionVisitor { if (type instanceof ptypes.FunctionPType) type = type.returnType const isGeneric = isGenericType(type) + const needsToCaptureTypeInfo = isGeneric && isStateOrBoxType(type) const isArc4Encoded = isArc4EncodedType(type) const info = isGeneric || isArc4Encoded ? getGenericTypeInfo(type) : undefined let updatedNode = node @@ -113,20 +115,22 @@ class ExpressionVisitor { updatedNode = nodeFactory.instantiateARC4EncodedType(updatedNode, info) } } + if (ts.isCallExpression(updatedNode)) { - const stubbedFunctionName = tryGetStubbedFunctionName(updatedNode, this.helper) - const infos = [info] + const stubbedFunctionName = this.stubbedFunctionName ?? tryGetStubbedFunctionName(updatedNode, this.helper) + this.stubbedFunctionName = undefined + let infoArg = info if (isCallingEmit(stubbedFunctionName)) { - infos[0] = this.helper.resolveTypeParameters(updatedNode).map(getGenericTypeInfo)[0] + infoArg = this.helper.resolveTypeParameters(updatedNode).map(getGenericTypeInfo)[0] } if (isCallingDecodeArc4(stubbedFunctionName)) { const targetType = ptypes.ptypeToArc4EncodedType(type, this.helper.sourceLocation(node)) const targetTypeInfo = getGenericTypeInfo(targetType) - infos[0] = targetTypeInfo + infoArg = targetTypeInfo } - updatedNode = stubbedFunctionName ? nodeFactory.callStubbedFunction(stubbedFunctionName, updatedNode, ...infos) : updatedNode + updatedNode = stubbedFunctionName ? nodeFactory.callStubbedFunction(stubbedFunctionName, updatedNode, infoArg) : updatedNode } - return isGeneric + return needsToCaptureTypeInfo ? nodeFactory.captureGenericTypeInfo(ts.visitEachChild(updatedNode, this.visit, this.context), JSON.stringify(info)) : ts.visitEachChild(updatedNode, this.visit, this.context) } @@ -218,8 +222,11 @@ class FunctionOrMethodVisitor { if (ts.isNewExpression(node)) { return new ExpressionVisitor(this.context, this.helper, node).result() } - if (ts.isCallExpression(node) && tryGetStubbedFunctionName(node, this.helper)) { - return new ExpressionVisitor(this.context, this.helper, node).result() + if (ts.isCallExpression(node)) { + const stubbedFunctionName = tryGetStubbedFunctionName(node, this.helper) + if (stubbedFunctionName) { + return new ExpressionVisitor(this.context, this.helper, node, stubbedFunctionName).result() + } } return node @@ -305,6 +312,9 @@ const isGenericType = (type: ptypes.PType): boolean => ptypes.TuplePType, ) +const isStateOrBoxType = (type: ptypes.PType): boolean => + instanceOfAny(type, ptypes.BoxMapPType, ptypes.BoxPType, ptypes.GlobalStateType, ptypes.LocalStateType) + const isArc4EncodedType = (type: ptypes.PType): boolean => instanceOfAny( type, From efc2d129660b2b0ea640e04fd731acf9c558266b Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 3 Jan 2025 11:54:34 +0800 Subject: [PATCH 83/85] refactor: remove extra util methods --- src/util.ts | 13 +++---- tests/arc4/address.spec.ts | 3 +- tests/arc4/bool.spec.ts | 2 +- tests/arc4/byte.spec.ts | 3 +- tests/arc4/str.spec.ts | 2 +- tests/arc4/uintn.spec.ts | 3 +- tests/crypto-op-codes.spec.ts | 4 +-- tests/global-state-arc4-values.spec.ts | 2 +- tests/log.spec.ts | 3 +- tests/primitives/biguint.spec.ts | 33 ++++++++---------- tests/primitives/bytes.spec.ts | 3 +- tests/pure-op-codes.spec.ts | 47 +++++++++++++++----------- tests/references/asset.spec.ts | 3 +- tests/state-op-codes.spec.ts | 3 +- tests/util.ts | 18 +--------- 15 files changed, 62 insertions(+), 80 deletions(-) diff --git a/src/util.ts b/src/util.ts index c139cd8..babf8f0 100644 --- a/src/util.ts +++ b/src/util.ts @@ -37,21 +37,18 @@ export const asBigInt = (v: internal.primitives.StubUint64Compat): bigint => asU export const asNumber = (v: internal.primitives.StubUint64Compat): number => asUint64Cls(v).asNumber() -export function extractGenericTypeArgs(t: string): string[] { - const match = t.match(/<(.*)>/) - if (!match) return [] - return match[1].split(',').map((x) => x.trim()) -} - export const asUint64Cls = (val: internal.primitives.StubUint64Compat) => internal.primitives.Uint64Cls.fromCompat(val) -export const asBigUintCls = (val: internal.primitives.StubBigUintCompat) => internal.primitives.BigUintCls.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 asBytesCls = (val: internal.primitives.StubBytesCompat | Uint8Array) => internal.primitives.BytesCls.fromCompat(val) export const asUint64 = (val: internal.primitives.StubUint64Compat) => asUint64Cls(val).asAlgoTs() -export const asBigUint = (val: internal.primitives.StubBigUintCompat) => asBigUintCls(val).asAlgoTs() +export const asBigUint = (val: internal.primitives.StubBigUintCompat | Uint8Array) => asBigUintCls(val).asAlgoTs() export const asBytes = (val: internal.primitives.StubBytesCompat | Uint8Array) => asBytesCls(val).asAlgoTs() diff --git a/tests/arc4/address.spec.ts b/tests/arc4/address.spec.ts index 6b388f8..c18c23b 100644 --- a/tests/arc4/address.spec.ts +++ b/tests/arc4/address.spec.ts @@ -4,8 +4,7 @@ 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 { encodeAddress } from '../../src/util' -import { asUint8Array } from '../util' +import { asUint8Array, encodeAddress } from '../../src/util' const abiTypeString = 'address' const testData = [ diff --git a/tests/arc4/bool.spec.ts b/tests/arc4/bool.spec.ts index ca58ded..2103d03 100644 --- a/tests/arc4/bool.spec.ts +++ b/tests/arc4/bool.spec.ts @@ -4,9 +4,9 @@ import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-te import { Bool, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/arc4' import { afterEach, describe, expect, test } 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 { asUint8Array } from '../util' describe('arc4.Bool', async () => { const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) diff --git a/tests/arc4/byte.spec.ts b/tests/arc4/byte.spec.ts index b094826..1cdcd1c 100644 --- a/tests/arc4/byte.spec.ts +++ b/tests/arc4/byte.spec.ts @@ -5,10 +5,9 @@ import { Byte, interpretAsArc4 } from '@algorandfoundation/algorand-typescript/a import { encodingUtil } from '@algorandfoundation/puya-ts' import { afterEach, describe, expect, it, test } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_UINT64 } from '../../src/constants' -import { asBigUintCls } from '../../src/util' +import { asBigUintCls, asUint8Array } from '../../src/util' import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' -import { asUint8Array } from '../util' const invalidBytesLengthError = 'byte string must be 1 byte long' describe('arc4.Byte', async () => { diff --git a/tests/arc4/str.spec.ts b/tests/arc4/str.spec.ts index 99cbc1d..a8e1b21 100644 --- a/tests/arc4/str.spec.ts +++ b/tests/arc4/str.spec.ts @@ -5,9 +5,9 @@ import { interpretAsArc4, Str } from '@algorandfoundation/algorand-typescript/ar import { encodingUtil } from '@algorandfoundation/puya-ts' import { afterEach, describe, expect, test } 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 { asUint8Array } from '../util' describe('arc4.Str', async () => { const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) diff --git a/tests/arc4/uintn.spec.ts b/tests/arc4/uintn.spec.ts index a12eff7..a4c41be 100644 --- a/tests/arc4/uintn.spec.ts +++ b/tests/arc4/uintn.spec.ts @@ -5,10 +5,9 @@ import { BitSize, interpretAsArc4, UintN, UintN16, UintN256, UintN32, UintN64, U import { encodingUtil } from '@algorandfoundation/puya-ts' import { afterEach, describe, expect, it, test } from 'vitest' import { ABI_RETURN_VALUE_LOG_PREFIX, MAX_UINT512, MAX_UINT64 } from '../../src/constants' -import { asBigUintCls } from '../../src/util' +import { asBigUintCls, asUint8Array } from '../../src/util' import appSpecJson from '../artifacts/arc4-primitive-ops/data/Arc4PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' -import { asUint8Array } from '../util' const invalidBytesLengthError = (length: number) => `byte string must correspond to a uint${length}` describe('arc4.UintN', async () => { diff --git a/tests/crypto-op-codes.spec.ts b/tests/crypto-op-codes.spec.ts index b6d98f1..2875019 100644 --- a/tests/crypto-op-codes.spec.ts +++ b/tests/crypto-op-codes.spec.ts @@ -9,10 +9,10 @@ import { afterEach, describe, expect, it, Mock, test, 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 { conactUint8Arrays, decodePublicKey } from '../src/util' +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 { asUint8Array, getPaddedBytes } from './util' +import { getPaddedBytes } from './util' const MAX_ARG_LEN = 2048 const curveMap = { diff --git a/tests/global-state-arc4-values.spec.ts b/tests/global-state-arc4-values.spec.ts index 9d35afb..c5be7e8 100644 --- a/tests/global-state-arc4-values.spec.ts +++ b/tests/global-state-arc4-values.spec.ts @@ -12,10 +12,10 @@ import { 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 { 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 { asUint8Array } from './util' describe('ARC4 AppGlobal values', async () => { const appClient = await getAlgorandAppClient(arc4AppGlobalAppSpecJson as AppSpec) diff --git a/tests/log.spec.ts b/tests/log.spec.ts index 4d29ddd..425cf24 100644 --- a/tests/log.spec.ts +++ b/tests/log.spec.ts @@ -17,11 +17,10 @@ import { import { afterEach, describe, expect, it } from 'vitest' import { MAX_UINT512, MAX_UINT64 } from '../src/constants' import { ApplicationTransaction } from '../src/impl/transactions' -import { asBigUint, asBigUintCls } from '../src/util' +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 { asUint8Array } from './util' describe('log', async () => { const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) diff --git a/tests/primitives/biguint.spec.ts b/tests/primitives/biguint.spec.ts index efbee2a..28031e8 100644 --- a/tests/primitives/biguint.spec.ts +++ b/tests/primitives/biguint.spec.ts @@ -5,12 +5,9 @@ import type { biguint } from '@algorandfoundation/algorand-typescript' import { BigUint, Bytes, internal, Uint64 } from '@algorandfoundation/algorand-typescript' import { describe, expect, it } from 'vitest' import { BIGUINT_OVERFLOW_UNDERFLOW_MESSAGE, MAX_UINT512, MAX_UINT64 } from '../../src/constants' -import { asUint64 } from '../../src/util' +import { asBigUint, asUint64 } from '../../src/util' import appSpecJson from '../artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' -import { abiAsBytes } from '../util' - -const asBigUint = (val: bigint | number) => (typeof val === 'bigint' ? BigUint(val) : BigUint(val)) describe('BigUint', async () => { const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) @@ -176,7 +173,7 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_add', bytesA, bytesB))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_add', bytesA, bytesB)) let result = bigUintA + bigUintB expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -200,7 +197,7 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_add', bytesA, bytesB))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_add', bytesA, bytesB)) let result = bigUintA + bigUintB expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -254,7 +251,7 @@ describe('BigUint', async () => { const uint64B = Uint64(b) const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_add_uint64', bytesA, b))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_add_uint64', bytesA, b)) let result = bigUintA + BigUint(uint64B) expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -283,7 +280,7 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_sub', bytesA, bytesB))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_sub', bytesA, bytesB)) let result = bigUintA - bigUintB expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -353,7 +350,7 @@ describe('BigUint', async () => { const uint64B = Uint64(b) const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_sub_uint64', bytesA, b))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_sub_uint64', bytesA, b)) const result = bigUintA - BigUint(uint64B) expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -378,7 +375,7 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_mul', bytesA, bytesB))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_mul', bytesA, bytesB)) let result = bigUintA * bigUintB expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -406,7 +403,7 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_mul', bytesA, bytesB))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_mul', bytesA, bytesB)) let result = bigUintA * bigUintB expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -461,7 +458,7 @@ describe('BigUint', async () => { const uint64B = asUint64(b) const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_mul_uint64', bytesA, b))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_mul_uint64', bytesA, b)) let result = bigUintA * BigUint(uint64B) expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -489,7 +486,7 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_div', bytesA, bytesB))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_div', bytesA, bytesB)) let result = bigUintA / bigUintB expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -562,7 +559,7 @@ describe('BigUint', async () => { const uint64B = asUint64(b) const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_div_uint64', bytesA, b))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_div_uint64', bytesA, b)) const result = bigUintA / BigUint(uint64B) expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -587,7 +584,7 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_mod', bytesA, bytesB))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_mod', bytesA, bytesB)) let result = bigUintA % bigUintB expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -659,7 +656,7 @@ describe('BigUint', async () => { const uint64B = asUint64(b) const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, 'verify_biguint_mod_uint64', bytesA, b))) + const avmResult = asBigUint(await getAvmResult({ appClient }, 'verify_biguint_mod_uint64', bytesA, b)) const result = bigUintA % BigUint(uint64B) expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -708,7 +705,7 @@ describe('BigUint', async () => { const bytesB = internal.encodingUtil.bigIntToUint8Array(bigUintB.valueOf()) it(`${a} ${operator} ${b}`, async () => { - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, bytesB))) + const avmResult = asBigUint(await getAvmResult({ appClient }, `verify_biguint_${op}`, bytesA, bytesB)) let result = getStubResult(bigUintA, bigUintB) expect(result, `for values: ${a}, ${b}`).toEqual(avmResult) @@ -736,7 +733,7 @@ describe('BigUint', async () => { const bytesA = internal.encodingUtil.bigIntToUint8Array(bigUintA.valueOf()) it(`${a} ${operator} ${b}`, async () => { - const avmResult = BigUint(abiAsBytes(await getAvmResult({ appClient }, `verify_biguint_${op}_uint64`, bytesA, b))) + 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) }) diff --git a/tests/primitives/bytes.spec.ts b/tests/primitives/bytes.spec.ts index 5a5b59f..edcee19 100644 --- a/tests/primitives/bytes.spec.ts +++ b/tests/primitives/bytes.spec.ts @@ -3,9 +3,10 @@ import { bytes, Bytes, internal } from '@algorandfoundation/algorand-typescript' import { describe, expect, it } from 'vitest' import { MAX_BYTES_SIZE } from '../../src/constants' import { sha256 } from '../../src/impl' +import { asUint8Array } from '../../src/util' import appSpecJson from '../artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from '../avm-invoker' -import { asUint8Array, getSha256Hash, padUint8Array } from '../util' +import { getSha256Hash, padUint8Array } from '../util' describe('Bytes', async () => { const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) diff --git a/tests/pure-op-codes.spec.ts b/tests/pure-op-codes.spec.ts index 7ab8575..6935465 100644 --- a/tests/pure-op-codes.spec.ts +++ b/tests/pure-op-codes.spec.ts @@ -10,10 +10,10 @@ import { UINT64_OVERFLOW_UNDERFLOW_MESSAGE, } from '../src/constants' import * as op from '../src/impl/pure' -import { asBigUintCls } from '../src/util' +import { asBigUintCls, asUint8Array } from '../src/util' import appSpecJson from './artifacts/miscellaneous-ops/data/MiscellaneousOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult, getAvmResultRaw } from './avm-invoker' -import { abiAsBytes, asUint8Array, base64Encode, base64UrlEncode, getPaddedBytes, getSha256Hash, intToBytes } from './util' +import { base64Encode, base64UrlEncode, getPaddedBytes, getSha256Hash, intToBytes } from './util' const avmIntArgOverflowError = 'is not a non-negative int or too big to fit in size' const extractOutOfBoundError = /extraction (start|end) \d+ is beyond length/ @@ -66,7 +66,7 @@ describe('Pure op codes', async () => { base64Encode(Bytes([0xff])), base64Encode(Bytes(Array(256).fill(0x00).concat([0xff]))), ])('should decode standard base64 string', async (a) => { - const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_base64_decode_standard', asUint8Array(a)))! + const avmResult = (await getAvmResult({ appClient }, 'verify_base64_decode_standard', asUint8Array(a)))! const result = op.base64Decode(Base64.StdEncoding, a) expect(result).toEqual(avmResult) }) @@ -89,7 +89,7 @@ describe('Pure op codes', async () => { base64UrlEncode(Bytes([0xff])), base64UrlEncode(Bytes(Array(256).fill(0x00).concat([0xff]))), ])('should decode base64url string', async (a) => { - const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_base64_decode_url', asUint8Array(a)))! + const avmResult = (await getAvmResult({ appClient }, 'verify_base64_decode_url', asUint8Array(a)))! const result = op.base64Decode(Base64.URLEncoding, a) expect(result).toEqual(avmResult) }) @@ -135,7 +135,7 @@ describe('Pure op codes', async () => { 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 = abiAsBytes(await getAvmResult({ appClient }, 'verify_bsqrt', uint8ArrayA))! + const avmResult = (await getAvmResult({ appClient }, 'verify_bsqrt', uint8ArrayA))! const result = op.bsqrt(a) const bytesResult = asBigUintCls(result).toBytes() @@ -174,7 +174,7 @@ 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 = abiAsBytes(await getAvmResult({ appClient }, 'verify_bzero', a))! + const avmResult = (await getAvmResult({ appClient }, 'verify_bzero', a))! const result = op.bzero(a) const resultHash = Bytes(getSha256Hash(asUint8Array(result))) expect(resultHash).toEqual(avmResult) @@ -202,9 +202,14 @@ describe('Pure op codes', async () => { ['1', '0', 0, MAX_BYTES_SIZE - 2], ['1', '0', MAX_BYTES_SIZE - 2, 0], ])('should retrun concatenated bytes', async (a, b, padASize, padBSize) => { - const avmResult = abiAsBytes( - await getAvmResult({ appClient }, 'verify_concat', asUint8Array(a), asUint8Array(b), padASize, padBSize), - )! + const avmResult = (await getAvmResult( + { appClient }, + 'verify_concat', + asUint8Array(a), + asUint8Array(b), + padASize, + padBSize, + ))! const paddedA = getPaddedBytes(padASize, a) const paddedB = getPaddedBytes(padBSize, b) @@ -424,7 +429,7 @@ describe('Pure op codes', async () => { [256, 3], ])(`should extract bytes from the input`, async (b, c) => { const a = 'hello, world'.repeat(30) - const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_extract', asUint8Array(a), b, c))! + const avmResult = (await getAvmResult({ appClient }, 'verify_extract', asUint8Array(a), b, c))! let result = op.extract(a, Uint64(b), Uint64(c)) expect(result).toEqual(avmResult) @@ -435,7 +440,7 @@ 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 = abiAsBytes(await getAvmResult({ appClient }, 'verify_extract_from_2', asUint8Array(a)))! + const avmResult = (await getAvmResult({ appClient }, 'verify_extract_from_2', asUint8Array(a)))! const result = op.extract(a, 2, 0) expect(result).toEqual(avmResult) }) @@ -661,7 +666,7 @@ describe('Pure op codes', async () => { describe('itob', async () => { test.each([0, 42, 100n, 256, 65535, MAX_UINT64])('should convert uint64 to bytes', async (a) => { - const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_itob', a))! + const avmResult = (await getAvmResult({ appClient }, 'verify_itob', a))! const result = op.itob(a) expect(result).toEqual(avmResult) }) @@ -728,7 +733,7 @@ describe('Pure op codes', async () => { ['hello, world.', 0, 'H'], ['', 0, ''], ])(`should replace bytes in the input`, async (a, b, c) => { - const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_replace', asUint8Array(a), b, asUint8Array(c)))! + const avmResult = (await getAvmResult({ appClient }, 'verify_replace', asUint8Array(a), b, asUint8Array(c)))! const result = op.replace(a, b, c) expect(result).toEqual(avmResult) }) @@ -756,9 +761,13 @@ describe('Pure op codes', async () => { [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) => { - const avmResult = abiAsBytes( - await getAvmResult({ appClient }, 'verify_select_bytes', asUint8Array(a), asUint8Array(b), c === true ? 1 : c === false ? 0 : c), - )! + const avmResult = (await getAvmResult( + { appClient }, + 'verify_select_bytes', + asUint8Array(a), + asUint8Array(b), + c === true ? 1 : c === false ? 0 : c, + ))! const result = op.select(a, b, c) expect(result).toEqual(avmResult) }) @@ -809,7 +818,7 @@ describe('Pure op codes', async () => { [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 = abiAsBytes(await getAvmResult({ appClient }, 'verify_setbit_bytes', asUint8Array(a), b, c))! + const avmResult = (await getAvmResult({ appClient }, 'verify_setbit_bytes', asUint8Array(a), b, c))! const result = op.setBit(a, b, c) as bytes expect(result).toEqual(avmResult) }) @@ -886,7 +895,7 @@ describe('Pure op codes', async () => { [intToBytes(MAX_UINT64), 0, 0], [intToBytes(MAX_UINT512), 0, 0], ])(`should set bytes in the input`, async (a, b, c) => { - const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_setbyte', asUint8Array(a), b, c))! + const avmResult = (await getAvmResult({ appClient }, 'verify_setbyte', asUint8Array(a), b, c))! const result = op.setByte(a, b, c) expect(result).toEqual(avmResult) }) @@ -1007,7 +1016,7 @@ describe('Pure op codes', async () => { ['hello, world.', 0, 13], ['', 0, 0], ])('should extract substring from the input', async (a, b, c) => { - const avmResult = abiAsBytes(await getAvmResult({ appClient }, 'verify_substring', asUint8Array(a), b, c)) + const avmResult = await getAvmResult({ appClient }, 'verify_substring', asUint8Array(a), b, c) const result = op.substring(a, b, c) expect(result).toEqual(avmResult) }) diff --git a/tests/references/asset.spec.ts b/tests/references/asset.spec.ts index cf534f3..980d72c 100644 --- a/tests/references/asset.spec.ts +++ b/tests/references/asset.spec.ts @@ -2,8 +2,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 { asBytes, asUint64 } from '../../src/util' -import { asUint8Array } from '../util' +import { asBytes, asUint64, asUint8Array } from '../../src/util' describe('Asset', () => { const ctx = new TestExecutionContext() diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 938c6fb..8e8a29b 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -12,7 +12,7 @@ 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 } from '../src/util' +import { asBigInt, asNumber, asUint64Cls, asUint8Array } from '../src/util' import { AppExpectingEffects } from './artifacts/created-app-asset/contract.algo' import { ItxnDemoContract, @@ -43,7 +43,6 @@ import { getLocalNetDefaultAccount, INITIAL_BALANCE_MICRO_ALGOS, } from './avm-invoker' -import { asUint8Array } from './util' describe('State op codes', async () => { const ctx = new TestExecutionContext() diff --git a/tests/util.ts b/tests/util.ts index ae307dc..37c5e6f 100644 --- a/tests/util.ts +++ b/tests/util.ts @@ -1,6 +1,6 @@ import { Bytes, bytes, internal } from '@algorandfoundation/algorand-typescript' import { createHash } from 'crypto' -import type { ABIValue } from './avm-invoker' +import { asUint8Array } from '../src/util' export const padUint8Array = (arr: Uint8Array, padSize: number): Uint8Array => { const paddedUint8Array = new Uint8Array(arr.length + padSize) @@ -8,9 +8,6 @@ export const padUint8Array = (arr: Uint8Array, padSize: number): Uint8Array => { return paddedUint8Array } -export const asUint8Array = (value: internal.primitives.StubBytesCompat): Uint8Array => - internal.primitives.BytesCls.fromCompat(value).asUint8Array() - export const base64Encode = (value: internal.primitives.StubBytesCompat): bytes => Bytes(Buffer.from(asUint8Array(value)).toString('base64')) @@ -28,16 +25,3 @@ export const getPaddedBytes = (padSize: number, value: internal.primitives.StubB export const intToBytes = (value: internal.primitives.StubBigUintCompat): internal.primitives.BytesCls => internal.primitives.BigUintCls.fromCompat(value).toBytes() - -export const abiAsBytes = (value: ABIValue) => { - if (Array.isArray(value) && value.every((i) => typeof i === 'number')) { - return Bytes(new Uint8Array(value)) - } - if (value instanceof Uint8Array) { - return Bytes(value) - } - if (typeof value === 'string') { - return Bytes(value) - } - throw new Error(`Value cannot be converted to bytes`) -} From 3b939fd54c4982208034f700460cfbb0bf3c0158 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 3 Jan 2025 12:07:13 +0800 Subject: [PATCH 84/85] refactor: encode ZERO_ADDRESS without using algosdk --- examples/htlc-logicsig/signature.algo.ts | 5 ++--- examples/htlc-logicsig/signature.spec.ts | 6 ++---- examples/rollup.config.ts | 9 ++++++--- src/constants.ts | 3 +-- src/impl/account.ts | 2 +- src/impl/global.ts | 2 +- tests/avm-invoker.ts | 1 - 7 files changed, 13 insertions(+), 15 deletions(-) diff --git a/examples/htlc-logicsig/signature.algo.ts b/examples/htlc-logicsig/signature.algo.ts index df6cf1f..8c83506 100644 --- a/examples/htlc-logicsig/signature.algo.ts +++ b/examples/htlc-logicsig/signature.algo.ts @@ -1,11 +1,10 @@ import { Account, Bytes, Global, LogicSig, op, TransactionType, Txn, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' -import algosdk from 'algosdk' export default class HashedTimeLockedLogicSig extends LogicSig { program(): boolean | uint64 { // Participants - const sellerAddress = Bytes(algosdk.decodeAddress('6ZHGHH5Z5CTPCF5WCESXMGRSVK7QJETR63M3NY5FJCUYDHO57VTCMJOBGY').publicKey) - const buyerAddress = Bytes(algosdk.decodeAddress('7Z5PWO2C6LFNQFGHWKSK5H47IQP5OJW2M3HA2QPXTY3WTNP5NU2MHBW27M').publicKey) + const sellerAddress = Bytes.fromBase32('6ZHGHH5Z5CTPCF5WCESXMGRSVK7QJETR63M3NY5FJCUYDHO57VTC') + const buyerAddress = Bytes.fromBase32('7Z5PWO2C6LFNQFGHWKSK5H47IQP5OJW2M3HA2QPXTY3WTNP5NU2M') const seller = Account(sellerAddress) const buyer = Account(buyerAddress) diff --git a/examples/htlc-logicsig/signature.spec.ts b/examples/htlc-logicsig/signature.spec.ts index c9cab8f..d819b05 100644 --- a/examples/htlc-logicsig/signature.spec.ts +++ b/examples/htlc-logicsig/signature.spec.ts @@ -1,11 +1,9 @@ import { Account, Bytes } from '@algorandfoundation/algorand-typescript' import { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing' -import algosdk from 'algosdk' import { afterEach, describe, expect, it } from 'vitest' import HashedTimeLockedLogicSig from './signature.algo' -const ZERO_ADDRESS_B32 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ' -const ZERO_ADDRESS = Bytes.fromBase32(ZERO_ADDRESS_B32) +const ZERO_ADDRESS = Bytes.fromBase32('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') describe('HTLC LogicSig', () => { const ctx = new TestExecutionContext() @@ -15,7 +13,7 @@ describe('HTLC LogicSig', () => { }) it('seller receives payment if correct secret is provided', () => { - const receiverAddress = Bytes(algosdk.decodeAddress('6ZHGHH5Z5CTPCF5WCESXMGRSVK7QJETR63M3NY5FJCUYDHO57VTCMJOBGY').publicKey) + const receiverAddress = Bytes.fromBase32('6ZHGHH5Z5CTPCF5WCESXMGRSVK7QJETR63M3NY5FJCUYDHO57VTC') ctx.txn .createScope([ ctx.any.txn.payment({ diff --git a/examples/rollup.config.ts b/examples/rollup.config.ts index d16a189..4aa1a7a 100644 --- a/examples/rollup.config.ts +++ b/examples/rollup.config.ts @@ -6,14 +6,17 @@ import { puyaTsTransformer } from '../src/test-transformer' const config: RollupOptions = { input: [ + 'examples/auction/contract.algo.ts', 'examples/calculator/contract.algo.ts', 'examples/hello-world-abi/contract.algo.ts', 'examples/hello-world/contract.algo.ts', - 'examples/auction/contract.algo.ts', - 'examples/voting/contract.algo.ts', + 'examples/htlc-logicsig/signature.algo.ts', + 'examples/precompiled/contract.algo.ts', + 'examples/scratch-storage/contract.algo.ts', 'examples/simple-voting/contract.algo.ts', + 'examples/tealscript/example.algo.ts', + 'examples/voting/contract.algo.ts', 'examples/zk-whitelist/contract.algo.ts', - 'examples/precompiled/contract.algo.ts', ], output: [ { diff --git a/src/constants.ts b/src/constants.ts index b218a66..20e9908 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -28,8 +28,7 @@ export const DEFAULT_GLOBAL_GENESIS_HASH = Bytes( ) // algorand encoded address of 32 zero bytes -export const ZERO_ADDRESS_B32 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ' -export const ZERO_ADDRESS = Bytes.fromBase32(ZERO_ADDRESS_B32) +export const ZERO_ADDRESS = Bytes.fromBase32('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') /** "\x09" # pragma version 9 diff --git a/src/impl/account.ts b/src/impl/account.ts index 0f5f67d..614d8a8 100644 --- a/src/impl/account.ts +++ b/src/impl/account.ts @@ -97,6 +97,6 @@ export class AccountCls extends BytesBackedCls implements Account { if (assetOrApp instanceof ApplicationCls) { return this.data.optedApplications.has(asUint64Cls(assetOrApp.id).asBigInt()) } - throw new internal.errors.InternalError('Invalid argument type. Must be an `algopy.Asset` or `algopy.Application` instance.') + throw new internal.errors.InternalError('Invalid argument type. Must be an `Asset` or `Application` instance.') } } diff --git a/src/impl/global.ts b/src/impl/global.ts index 5418937..393cc88 100644 --- a/src/impl/global.ts +++ b/src/impl/global.ts @@ -42,7 +42,7 @@ const getGlobalData = (): GlobalData => { } const getMissingValueErrorMessage = (name: keyof GlobalData) => - `'algopy.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."` + `'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 = { /** diff --git a/tests/avm-invoker.ts b/tests/avm-invoker.ts index b54e858..844ff7c 100644 --- a/tests/avm-invoker.ts +++ b/tests/avm-invoker.ts @@ -90,7 +90,6 @@ export const generateAVMTestAccount = async (): Promise => { - // const account = generateAccount() const account = await generateAVMTestAccount() return Account(Bytes.fromBase32(account.addr.toString())) } From db3c6279c95fb0c2891b6a2ce49066ae53bf70d6 Mon Sep 17 00:00:00 2001 From: Bobby Lat Date: Fri, 3 Jan 2025 13:36:43 +0800 Subject: [PATCH 85/85] refactor: make parallel calls to avm in test to reduce wait time in tests --- tests/primitives/uint64.spec.ts | 6 ++--- tests/state-op-codes.spec.ts | 40 +++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/tests/primitives/uint64.spec.ts b/tests/primitives/uint64.spec.ts index c5abea8..2d56dc9 100644 --- a/tests/primitives/uint64.spec.ts +++ b/tests/primitives/uint64.spec.ts @@ -1,13 +1,11 @@ import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' import { internal, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { describe, expect, it } from 'vitest' -import { UINT64_OVERFLOW_UNDERFLOW_MESSAGE } from '../../src/constants' +import { MAX_UINT64, UINT64_OVERFLOW_UNDERFLOW_MESSAGE } from '../../src/constants' +import { asUint64 } from '../../src/util' import appSpecJson from '../artifacts/primitive-ops/data/PrimitiveOpsContract.arc32.json' import { getAlgorandAppClient, getAvmResult } from '../avm-invoker' -const MAX_UINT64 = 2n ** 64n - 1n -const asUint64 = (val: bigint | number) => (typeof val === 'bigint' ? Uint64(val) : Uint64(val)) - describe('Unit64', async () => { const appClient = await getAlgorandAppClient(appSpecJson as AppSpec) diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 8e8a29b..84326de 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -52,8 +52,7 @@ describe('State op codes', async () => { }) describe('AcctParams', async () => { - const appClient = await getAlgorandAppClient(acctParamsAppSpecJson as AppSpec) - const dummyAccount = await generateTestAccount() + const [appClient, dummyAccount] = await Promise.all([getAlgorandAppClient(acctParamsAppSpecJson as AppSpec), generateTestAccount()]) test.each([ ['verify_acct_balance', INITIAL_BALANCE_MICRO_ALGOS + 100_000], @@ -100,8 +99,11 @@ describe('State op codes', async () => { }) describe('AppParams', async () => { - const [appClient, app] = await getAlgorandAppClientWithApp(appParamsAppSpecJson as AppSpec) - const dummyAccount = await getLocalNetDefaultAccount() + const [[appClient, app], dummyAccount] = await Promise.all([ + getAlgorandAppClientWithApp(appParamsAppSpecJson as AppSpec), + getLocalNetDefaultAccount(), + ]) + test.each([ ['verify_app_params_get_approval_program', undefined], ['verify_app_params_get_clear_state_program', undefined], @@ -142,8 +144,11 @@ describe('State op codes', async () => { }) describe('AssetHolding', async () => { - const appClient = await getAlgorandAppClient(assetHoldingAppSpecJson as AppSpec) - const dummyAccount = await getLocalNetDefaultAccount() + const [appClient, dummyAccount] = await Promise.all([ + getAlgorandAppClient(assetHoldingAppSpecJson as AppSpec), + getLocalNetDefaultAccount(), + ]) + test.each([ ['verify_asset_holding_get', 100], ['verify_asset_frozen_get', false], @@ -174,8 +179,10 @@ describe('State op codes', async () => { }) describe('AssetParams', async () => { - const appClient = await getAlgorandAppClient(assetParamsAppSpecJson as AppSpec) - const dummyAccount = await getLocalNetDefaultAccount() + const [appClient, dummyAccount] = await Promise.all([ + getAlgorandAppClient(assetParamsAppSpecJson as AppSpec), + getLocalNetDefaultAccount(), + ]) test.each([ ['verify_asset_params_get_total', 100n], @@ -437,8 +444,11 @@ describe('State op codes', async () => { }) describe('AppGlobal', async () => { - const appClient = await getAlgorandAppClient(appGlobalAppSpecJson as AppSpec) - const [_exAppClient, exApp] = await getAlgorandAppClientWithApp(appGlobalExAppSpecJson as AppSpec) + 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 () => { const bytesKey = 'global_bytes' const uint64Key = 'global_uint64' @@ -510,10 +520,12 @@ describe('State op codes', async () => { }) describe('AppLocal', async () => { - const appClient = await getAlgorandAppClient(appLocalAppSpecJson as AppSpec) - const [exAppClient, exApp] = await getAlgorandAppClientWithApp(appLocalExAppSpecJson as AppSpec) - await tryOptIn(appClient) - await tryOptIn(exAppClient) + 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()