diff --git a/.github/workflows/tact.yml b/.github/workflows/tact.yml
index 9bdc67ca9..81c4eafe2 100644
--- a/.github/workflows/tact.yml
+++ b/.github/workflows/tact.yml
@@ -20,10 +20,10 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Node.js 18 for backwards compat tests
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
node-version: 18
# without caching
@@ -46,7 +46,7 @@ jobs:
yarn config delete ignore-engines
- name: Setup Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "yarn"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 77316a572..0206212e7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -84,7 +84,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Wider range of serialization options for integers — `uint1` through `uint256` and `int1` through `int257`: PR [#558](https://github.com/tact-lang/tact/pull/558), PR [#937](https://github.com/tact-lang/tact/pull/937)
- The `deepEquals` method for the `Map` type: PR [#637](https://github.com/tact-lang/tact/pull/637), PR [#939](https://github.com/tact-lang/tact/pull/939)
- `asm` bodies for module-level functions: PR [#769](https://github.com/tact-lang/tact/pull/769), PR [#825](https://github.com/tact-lang/tact/pull/825)
-- Corresponding stdlib functions for new TVM instructions from 2023.07 and 2024.04 upgrades: PR [#331](https://github.com/tact-lang/tact/pull/331). Added the `storeBuilder` extension function and `gasConsumed`, `getComputeFee`, `getStorageFee`, `getForwardFee`, `getSimpleComputeFee`, `getSimpleForwardFee`, `getOriginalFwdFee`, `myStorageDue` functions.
+- Corresponding stdlib functions for new TVM instructions from 2023.07 and 2024.04 upgrades: PR [#331](https://github.com/tact-lang/tact/pull/331), PR [#1062](https://github.com/tact-lang/tact/pull/1062). Added the `storeBuilder` extension function and `gasConsumed`, `getComputeFee`, `getStorageFee`, `getForwardFee`, `getSimpleComputeFee`, `getSimpleForwardFee`, `getOriginalFwdFee`, `myStorageDue` functions.
- `slice`, `rawSlice`, `ascii` and `crc32` built-in functions: PR [#787](https://github.com/tact-lang/tact/pull/787), PR [#799](https://github.com/tact-lang/tact/pull/799), PR [#951](https://github.com/tact-lang/tact/pull/951)
- `Builder.storeMaybeRef`, `parseStdAddress` and `parseVarAddress` stdlib functions: PR [#793](https://github.com/tact-lang/tact/pull/793), PR [#950](https://github.com/tact-lang/tact/pull/950)
- The compiler development guide: PR [#833](https://github.com/tact-lang/tact/pull/833)
diff --git a/cspell.json b/cspell.json
index 90d2f5036..9765867ba 100644
--- a/cspell.json
+++ b/cspell.json
@@ -47,6 +47,7 @@
"funs",
"frontmatter",
"Georgiy",
+ "getsimpleforwardfee",
"gettest",
"Héctor",
"infixl",
diff --git a/docs/src/content/docs/book/debug.mdx b/docs/src/content/docs/book/debug.mdx
index a3305ec88..fde2420c9 100644
--- a/docs/src/content/docs/book/debug.mdx
+++ b/docs/src/content/docs/book/debug.mdx
@@ -693,7 +693,7 @@ If you're overwhelmed by the testing setup of [Blueprint][bp] or just want to te
```json filename="package.json" {3}
{
"scripts": {
- "lab": "blueprint build 1>/dev/null && yarn test -t plays"
+ "lab": "blueprint build --all 1>/dev/null && yarn test -t plays"
}
}
```
@@ -703,7 +703,7 @@ If you're overwhelmed by the testing setup of [Blueprint][bp] or just want to te
```json filename="package.json" {3-4}
{
"scripts": {
- "build": "blueprint build | out-null",
+ "build": "blueprint build --all | out-null",
"lab": "yarn build && yarn test -t plays"
}
}
diff --git a/docs/src/content/docs/book/security-best-practices.mdx b/docs/src/content/docs/book/security-best-practices.mdx
index 105d50021..acd2a2d7e 100644
--- a/docs/src/content/docs/book/security-best-practices.mdx
+++ b/docs/src/content/docs/book/security-best-practices.mdx
@@ -128,8 +128,10 @@ message Sample {
parsedField: Slice;
}
-receive(msg: Sample) {
- // Process msg.parsedField directly
+contract Example {
+ receive(msg: Sample) {
+ // Process msg.parsedField directly
+ }
}
```
@@ -138,13 +140,13 @@ receive(msg: Sample) {
Avoid parsing strings from human-readable formats into binary structures **on-chain**, as this increases computational overhead and gas costs.
```tact
-message Sample {
- field: String;
-}
+message Sample { field: String }
-receive(msg: Sample) {
- // Parsing occurs on-chain, which is inefficient
- let parsed = field.fromBase64();
+contract Example {
+ receive(msg: Sample) {
+ // Parsing occurs on-chain, which is inefficient
+ let parsed = field.fromBase64();
+ }
}
```
@@ -155,11 +157,9 @@ Be careful with the `Out of gas error`. It cannot be handled, so try to pre-calc
##### Do's ✅
```tact
-message Vote {
- votes: Int as int32;
-}
+message Vote { votes: Int as int32 }
-contract Sample2 {
+contract Example {
const voteGasUsage = 10000; // precompute with tests
receive(msg: Vote) {
@@ -360,7 +360,7 @@ Return excesses using a [Message][message] with `0xd53276db` opcode.
```tact
message(0xd53276db) Excesses {}
-message Vote { votes: Int as int32; }
+message Vote { votes: Int as int32 }
contract Sample {
votes: Int as uint32 = 0;
@@ -378,14 +378,11 @@ contract Sample {
}
```
-Also, you can leverage [`notify():{tact}`](/ref/core-base/#self-notify) or [`forward():{tact}`](/ref/core-base/#self-forward) standard functions.
+Also, you can leverage [`notify(){:tact}`](/ref/core-base/#self-notify) or [`forward(){:tact}`](/ref/core-base/#self-forward) standard functions.
```tact
-message Vote {
- votes: Int as int32;
-}
-
message(0xd53276db) Excesses {}
+message Vote { votes: Int as int32 }
contract Sample {
votes: Int as uint32 = 0;
@@ -409,12 +406,8 @@ Thus, any on-chain communication is asynchronous and done by sending and receivi
Exchange messages to pull data from other contract.
```tact
-message ProvideMoney {
-}
-
-message TakeMoney {
- money: Int as coins;
-}
+message ProvideMoney {}
+message TakeMoney { money: Int as coins }
contract OneContract {
money: Int as coins;
diff --git a/docs/src/content/docs/ref/core-advanced.mdx b/docs/src/content/docs/ref/core-advanced.mdx
index 8bbdcd726..25dba26cd 100644
--- a/docs/src/content/docs/ref/core-advanced.mdx
+++ b/docs/src/content/docs/ref/core-advanced.mdx
@@ -13,22 +13,269 @@ Various niche, dangerous or unstable features which can produce unexpected resul
:::
+## gasConsumed
+
+
+
+```tact
+fun gasConsumed(): Int;
+```
+
+Returns the [nanoToncoin][nanotoncoin] [`Int{:tact}`][int] amount of [gas][gas] consumed by [TVM][tvm] in the current transaction so far. The resulting value includes the cost of calling this function.
+
+Usage example:
+
+```tact
+let gas: Int = gasConsumed();
+```
+
+:::note[Useful links:]
+
+ [Gas in TON Docs](https://docs.ton.org/v3/documentation/smart-contracts/transaction-fees/fees#gas)
+
+:::
+
+## myStorageDue
+
+
+
+```tact
+fun myStorageDue(): Int;
+```
+
+Returns the [nanoToncoin][nanotoncoin] [`Int{:tact}`][int] amount of the accumulated [storage fee][storage-fee] debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.
+
+Usage example:
+
+```tact
+let debt: Int = myStorageDue();
+```
+
+:::note[Useful links:]
+
+ [Storage fee in TON Docs][storage-fee]\
+ [Storage fee calculation in TON Docs][storage-fee-calc]
+
+:::
+
+## getStorageFee
+
+
+
+```tact
+fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int;
+```
+
+Calculates and returns the [storage fee][storage-fee] in [nanoToncoins][nanotoncoin] [`Int{:tact}`][int] for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the [masterchain][masterchain] if `isMasterchain` is `true{:tact}`, otherwise the prices of the [basechain][basechain]. The current prices are obtained from the [config param 18 of TON Blockchain](https://docs.ton.org/develop/howto/blockchain-configs#param-18).
+
+Note, that the values of `cells` and `bits` are taken modulo their maximum values plus $1$. That is, specifying values higher than those listed in [account state limits (`max_acc_state_cells` and `max_acc_state_bits`)](/book/exit-codes#50) will have the same result as with specifying the exact limits. In addition, make sure you take into account the [deduplication of cells with the same hash][deduplication].
+
+Attempts to specify negative number of `cells`, `bits` or `seconds` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.
+
+Usage example:
+
+```tact
+let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);
+// ----- ----- ----- -----
+// ↑ ↑ ↑ ↑
+// | | | Isn't on the masterchain,
+// | | | but on the basechain
+// | | Number of seconds to calculate
+// | | the storage fee for
+// | Number of bits in a contract
+// Number of cells in a contract
+```
+
+:::note[Useful links:]
+
+ [Storage fee in TON Docs][storage-fee]\
+ [Storage fee calculation in TON Docs][storage-fee-calc]
+
+:::
+
+## getComputeFee
+
+
+
+```tact
+fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int;
+```
+
+Calculates and returns the [compute fee][compute-fee] in [nanoToncoins][nanotoncoin] [`Int{:tact}`][int] for a transaction that consumed `gasUsed` amount of [gas][gas]. Uses the prices of the [masterchain][masterchain] if `isMasterchain` is `true{:tact}`, otherwise the prices of the [basechain][basechain]. The current prices are obtained from the [config param 20 for the masterchain and config param 21 for the basechain][param-20-21] of TON Blockchain.
+
+When the `gasUsed` is less than a certain threshold called [`flat_gas_limit`][param-20-21], there's a minimum price to pay based on the value of [`flat_gas_price`][param-20-21]. The less gas is used below this threshold, the higher the minimum price will be. See the example for [`getSimpleComputeFee(){:tact}`](#getsimplecomputefee) to derive that threshold.
+
+Attempts to specify negative value of `gasUsed` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.
+
+Usage example:
+
+```tact
+let fee: Int = getComputeFee(1_000, false);
+// ----- -----
+// ↑ ↑
+// | Isn't on the masterchain,
+// | but on the basechain
+// Number of gas units
+// consumed per transaction
+```
+
+:::note[Useful links:]
+
+ [Compute fee in TON Docs][compute-fee]\
+ [Compute fee calculation in TON Docs][compute-fee-calc]\
+ [`getSimpleComputeFee(){:tact}`](#getsimplecomputefee)
+
+:::
+
+## getSimpleComputeFee
+
+
+
+```tact
+fun getSimpleComputeFee(gasUsed: Int, isMasterchain: Bool): Int;
+```
+
+Similar to [`getComputeFee(){:tact}`](#getcomputefee), but without the [`flat_gas_price`][param-20-21], i.e. without a minimum price to pay if the `gasUsed` is less than a certain threshold called [`flat_gas_limit`][param-20-21]. Calculates and returns only the `gasUsed` times the current gas price.
+
+Attempts to specify negative value of `gasUsed` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.
+
+Usage example:
+
+```tact
+let fee = getComputeFee(0, false);
+let feeNoFlat = getSimpleComputeFee(0, false);
+let maxFlatPrice = fee - feeNoFlat;
+```
+
+:::note[Useful links:]
+
+ [Compute fee in TON Docs][compute-fee]\
+ [Compute fee calculation in TON Docs][compute-fee-calc]\
+ [`getComputeFee(){:tact}`](#getcomputefee)
+
+:::
+
## Context.readForwardFee
```tact
-extends fun readForwardFee(self: Context): Int
+extends fun readForwardFee(self: Context): Int;
```
Extension function for the [`Context{:tact}`](/ref/core-common#context).
-Reads [forward fee](https://docs.ton.org/develop/smart-contracts/guidelines/processing) and returns it as [`Int{:tact}`][int] amount of [nanoToncoins](/book/integers#nanotoncoin).
+Reads [forward fee](https://docs.ton.org/develop/smart-contracts/guidelines/processing) and returns it as [`Int{:tact}`][int] amount of [nanoToncoins][nanotoncoin].
+
+Usage example:
+
+```tact
+let fwdFee: Int = context().readForwardFee();
+```
+
+:::note[Useful links:]
+
+ [`getOriginalFwdFee(){:tact}`](#getoriginalfwdfee)
+
+:::
+
+## getForwardFee
+
+
+
+```tact
+fun getForwardFee(cells: Int, bits: Int, isMasterchain: Bool): Int;
+```
+
+Calculates and returns the [forward fee][forward-fee] in [nanoToncoins][nanotoncoin] [`Int{:tact}`][int] for an outgoing message consisting of a given number of `cells` and `bits`. Uses the prices of the [masterchain][masterchain] if `isMasterchain` is `true{:tact}`, otherwise the prices of the [basechain][basechain]. The current prices are obtained from the [config param 24 for the masterchain and config param 25 for the basechain][param-24-25] of TON Blockchain.
+
+If both the source and the destination addresses are in the [basechain][basechain], then specify `isMasterchain` as `false{:tact}`. Otherwise, specify `true{:tact}`.
+
+Note, that the values of `cells` and `bits` are taken modulo their maximum values plus $1$. That is, specifying values higher than those listed in [account state limits (`max_msg_cells` and `max_msg_bits`)](/book/exit-codes#50) will have the same result as with specifying the exact limits.
+
+However, regardless of the values of `cells` and `bits`, this function always adds the minimum price based on the value of [`lump_price`][param-24-25]. See the example for [`getSimpleForwardFee(){:tact}`](#getsimpleforwardfee) to derive it. In addition, make sure you take into account the [deduplication of cells with the same hash][deduplication], since for example the root cell and its data bits don't count towards the forward fee and are covered by the [`lump_price`][param-24-25].
+
+Attempts to specify negative number of `cells` or `bits` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.
+
+Usage example:
+
+```tact
+let fee: Int = getForwardFee(1_000, 1_000, false);
+// ----- ----- -----
+// ↑ ↑ ↑
+// | | Both source and destination
+// | | isn't on the masterchain,
+// | | but on the basechain
+// | Number of bits in a message
+// Number of cells in a message
+```
+
+:::note[Useful links:]
+
+ [Forward fee in TON Docs][forward-fee]\
+ [Forward fee calculation in TON Docs][forward-fee-calc]\
+ [`CDATASIZEQ` instruction for computing the number of distinct cells, data bits and refs in a `Cell{:tact}`](https://docs.ton.org/v3/documentation/tvm/instructions#F940)\
+ [`getSimpleForwardFee(){:tact}`](#getsimpleforwardfee)\
+ [`getOriginalFwdFee(){:tact}`](#getoriginalfwdfee)
+
+:::
+
+## getSimpleForwardFee
+
+
+
+```tact
+fun getSimpleForwardFee(cells: Int, bits: Int, isMasterchain: Bool): Int;
+```
+
+Similar to [`getForwardFee(){:tact}`](#getforwardfee), but without the [`lump_price`][param-24-25], i.e. without the minimum price to pay regardless of the amount of `cells` or `bits`. Calculates and returns only the `cells` times the current cell price plus `bits` times the current bit price.
+
+Attempts to specify negative number of `cells` or `bits` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.
+
+Usage example:
+
+```tact
+let fee = getForwardFee(1_000, 1_000, false);
+let feeNoLump = getSimpleForwardFee(1_000, 1_000, false);
+let lumpPrice = fee - feeNoLump;
+```
+
+:::note[Useful links:]
+
+ [Forward fee in TON Docs][forward-fee]\
+ [Forward fee calculation in TON Docs][forward-fee-calc]\
+ [`getForwardFee(){:tact}`](#getforwardfee)
+
+:::
+
+## getOriginalFwdFee
+
+
+
+```tact
+fun getOriginalFwdFee(fwdFee: Int, isMasterchain: Bool): Int;
+```
+
+Calculates and returns the so-called _original_ [forward fee][forward-fee] in [nanoToncoins][nanotoncoin] [`Int{:tact}`][int] for an outgoing message based on the `fwdFee` obtained from the incoming message. If both the source and the destination addresses are in the [basechain][basechain], then specify `isMasterchain` as `false{:tact}`. Otherwise, specify `true{:tact}`.
+
+This function is useful when the outgoing message depends heavily on the structure of the incoming message, so much so that you cannot fully predict the fee using [`getForwardFee(){:tact}`](#getforwardfee) alone. Even if you could, calculating the exact fee with [nanoToncoin][nanotoncoin]-level precision can be very expensive, so the approximation given by this function is often good enough.
+
+Attempts to specify a negative value of `fwdFee` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`.
Usage example:
```tact
let fwdFee: Int = context().readForwardFee();
+let origFee: Int = getOriginalFwdFee(fee, false);
```
+:::note[Useful links:]
+
+ [Forward fee in TON Docs][forward-fee]\
+ [Forward fee calculation in TON Docs][forward-fee-calc]\
+ [`getForwardFee(){:tact}`](#getforwardfee)\
+ [`Context.readForwardFee(){:tact}`](#contextreadforwardfee)
+
+:::
+
## getConfigParam
```tact
@@ -199,7 +446,7 @@ fun nativeSendMessage(cell: Cell, mode: Int);
fun nativeReserve(amount: Int, mode: Int);
```
-Calls native `raw_reserve` function with specified amount and mode. The `raw_reserve` is a function that creates an output action to reserve a specific amount of [nanoToncoins](/book/integers#nanotoncoin) from the remaining balance of the account.
+Calls native `raw_reserve` function with specified amount and mode. The `raw_reserve` is a function that creates an output action to reserve a specific amount of [nanoToncoins][nanotoncoin] from the remaining balance of the account.
It has the following signature in FunC:
@@ -208,10 +455,10 @@ raw_reserve(int amount, int mode) impure asm "RAWRESERVE";
```
The function takes two arguments:
-* `amount`: The number of [nanoToncoins](/book/integers#nanotoncoin) to reserve.
+* `amount`: The number of [nanoToncoins][nanotoncoin] to reserve.
* `mode`: Determines the reservation behavior.
-Function `raw_reserve` is roughly equivalent to creating an outbound message carrying the specified `amount` of [nanoToncoins](/book/integers#nanotoncoin) (or `b` $-$ `amount` [nanoToncoins](/book/integers#nanotoncoin), where `b` is the remaining balance) to oneself. This ensures that subsequent output actions cannot spend more money than the remainder.
+Function `raw_reserve` is roughly equivalent to creating an outbound message carrying the specified `amount` of [nanoToncoins][nanotoncoin] (or `b` $-$ `amount` [nanoToncoins][nanotoncoin], where `b` is the remaining balance) to oneself. This ensures that subsequent output actions cannot spend more money than the remainder.
It's possible to use raw [`Int{:tact}`][int] values and manually provide them for the `mode`, but for your convenience there's a set of constants which you may use to construct the compound `mode` with ease. Take a look at the following tables for more information on base modes and optional flags.
@@ -227,9 +474,9 @@ The resulting `mode` value can have the following base modes:
Mode value | Constant name | Description
---------: | :---------------------------- | -----------
-$0$ | `ReserveExact{:tact}` | Reserves exactly the specified `amount` of [nanoToncoins](/book/integers#nanotoncoin).
-$1$ | `ReserveAllExcept{:tact}` | Reserves all, but the specified `amount` of [nanoToncoins](/book/integers#nanotoncoin).
-$2$ | `ReserveAtMost{:tact}` | Reserves at most the specified `amount` of [nanoToncoins](/book/integers#nanotoncoin).
+$0$ | `ReserveExact{:tact}` | Reserves exactly the specified `amount` of [nanoToncoins][nanotoncoin].
+$1$ | `ReserveAllExcept{:tact}` | Reserves all, but the specified `amount` of [nanoToncoins][nanotoncoin].
+$2$ | `ReserveAtMost{:tact}` | Reserves at most the specified `amount` of [nanoToncoins][nanotoncoin].
### Optional flags {#nativereserve-optional-flags}
@@ -334,3 +581,22 @@ parsedVarAddr.address.loadUint(123); // 345
[int]: /book/integers
[slice]: /book/cells#slices
[s]: /book/structs-and-messages#structs
+[masterchain]: /book/masterchain
+[cell-hash]: /ref/core-cell#cellhash
+[nanotoncoin]: /book/integers#nanotoncoin
+
+[tvm]: https://docs.ton.org/learn/tvm-instructions/tvm-overview
+[basechain]: https://docs.ton.org/v3/concepts/ton-blockchain/smart-contract-addresses#address-components
+[deduplication]: https://docs.ton.org/v3/documentation/data-formats/tlb/library-cells
+
+[storage-fee]: https://docs.ton.org/v3/documentation/smart-contracts/transaction-fees/fees-low-level#storage-fee
+[storage-fee-calc]: https://docs.ton.org/v3/guidelines/smart-contracts/fee-calculation#storage-fee
+
+[gas]: https://docs.ton.org/v3/documentation/smart-contracts/transaction-fees/fees#gas
+[compute-fee]: https://docs.ton.org/v3/documentation/smart-contracts/transaction-fees/fees-low-level#computation-fees
+[compute-fee-calc]: https://docs.ton.org/v3/guidelines/smart-contracts/fee-calculation#computation-fee
+[param-20-21]: https://docs.ton.org/v3/documentation/network/configs/blockchain-configs#param-20-and-21
+
+[forward-fee]: https://docs.ton.org/v3/documentation/smart-contracts/transaction-fees/forward-fees
+[forward-fee-calc]: https://docs.ton.org/v3/guidelines/smart-contracts/fee-calculation#forward-fee
+[param-24-25]: https://docs.ton.org/v3/documentation/network/configs/blockchain-configs#param-24-and-25
diff --git a/docs/src/content/docs/ref/core-cells.mdx b/docs/src/content/docs/ref/core-cells.mdx
index f29d38650..770130032 100644
--- a/docs/src/content/docs/ref/core-cells.mdx
+++ b/docs/src/content/docs/ref/core-cells.mdx
@@ -209,6 +209,24 @@ let fizz: Builder = b.storeBit(true); // writes 1
let buzz: Builder = b.storeBit(false); // writes 0
```
+## Builder.storeBuilder
+
+```tact
+extends fun storeBuilder(self: Builder, cell: Builder): Builder;
+```
+
+Extension function for the [`Builder{:tact}`][builder].
+
+Appends all data from a [`Builder{:tact}`][builder] `cell` to the copy of the [`Builder{:tact}`][builder]. Returns that copy.
+
+Usage example:
+
+```tact
+let b: Builder = beginCell().storeCoins(42);
+let fizz: Builder = beginCell().storeBuilder(b);
+b.endCell() == fizz.endCell(); // true
+```
+
## Builder.storeSlice
```tact
diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts
index a79113eed..f38b5ce7c 100644
--- a/src/imports/stdlib.ts
+++ b/src/imports/stdlib.ts
@@ -128,62 +128,69 @@ files['std/cells.tact'] =
'bnQsIGJpdHM6IEludCk6IEJ1aWxkZXI7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIlNUVVgi' +
'CkBuYW1lKHN0b3JlX3VpbnQpCmV4dGVuZHMgbmF0aXZlIHN0b3JlVWludChzZWxmOiBCdWlsZGVyLCB2YWx1ZTogSW50LCBiaXRzOiBJbnQpOiBCdWlsZGVyOwoKQG5h' +
'bWUoX190YWN0X3N0b3JlX2Jvb2wpCmV4dGVuZHMgbmF0aXZlIHN0b3JlQm9vbChzZWxmOiBCdWlsZGVyLCB2YWx1ZTogQm9vbCk6IEJ1aWxkZXI7CgovLy8gRXh0ZW5z' +
- 'aW9uIGZ1bmN0aW9uIGZvciB0aGUgYEJ1aWxkZXJgLiBBbGlhcyB0byBgQnVpbGRlci5zdG9yZUJvb2woKWAuCi8vLwovLy8gYGBgdGFjdAovLy8gbGV0IGI6IEJ1aWxk' +
- 'ZXIgPSBiZWdpbkNlbGwoKTsKLy8vIGxldCBmaXp6OiBCdWlsZGVyID0gYi5zdG9yZUJpdCh0cnVlKTsgIC8vIHdyaXRlcyAxCi8vLyBsZXQgYnV6ejogQnVpbGRlciA9' +
- 'IGIuc3RvcmVCaXQoZmFsc2UpOyAvLyB3cml0ZXMgMAovLy8gYGBgCi8vLwovLy8gQHNpbmNlIFRhY3QgMS41LjAKLy8vIEBzZWUgaHR0cHM6Ly9kb2NzLnRhY3QtbGFu' +
- 'Zy5vcmcvcmVmL2NvcmUtY2VsbHMjYnVpbGRlcnN0b3JlYml0Ci8vLwpAbmFtZShfX3RhY3Rfc3RvcmVfYm9vbCkKZXh0ZW5kcyBuYXRpdmUgc3RvcmVCaXQoc2VsZjog' +
- 'QnVpbGRlciwgdmFsdWU6IEJvb2wpOiBCdWlsZGVyOwoKYXNtIGV4dGVuZHMgZnVuIHN0b3JlQ29pbnMoc2VsZjogQnVpbGRlciwgdmFsdWU6IEludCk6IEJ1aWxkZXIg' +
- 'eyBTVFZBUlVJTlQxNiB9Cgphc20oY2VsbCBzZWxmKSBleHRlbmRzIGZ1biBzdG9yZVJlZihzZWxmOiBCdWlsZGVyLCBjZWxsOiBDZWxsKTogQnVpbGRlciB7IFNUUkVG' +
- 'IH0KCmFzbSBleHRlbmRzIGZ1biBzdG9yZVNsaWNlKHNlbGY6IEJ1aWxkZXIsIGNlbGw6IFNsaWNlKTogQnVpbGRlciB7IFNUU0xJQ0VSIH0KCmFzbSBleHRlbmRzIGZ1' +
- 'biBzdG9yZUJ1aWxkZXIoc2VsZjogQnVpbGRlciwgY2VsbDogQnVpbGRlcik6IEJ1aWxkZXIgeyBTVEJSIH0KCkBuYW1lKF9fdGFjdF9zdG9yZV9hZGRyZXNzKQpleHRl' +
- 'bmRzIG5hdGl2ZSBzdG9yZUFkZHJlc3Moc2VsZjogQnVpbGRlciwgYWRkcmVzczogQWRkcmVzcyk6IEJ1aWxkZXI7CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0' +
- 'aGUgYEJ1aWxkZXJgLgovLy8KLy8vIElmIHRoZSBgY2VsbGAgaXMgbm90IGBudWxsYCwgc3RvcmVzIDEgYXMgYSBzaW5nbGUgYml0IGFuZCB0aGVuIHJlZmVyZW5jZSBg' +
- 'Y2VsbGAgaW50byB0aGUgY29weSBvZiB0aGUgYEJ1aWxkZXJgLiBSZXR1cm5zIHRoYXQgY29weS4KLy8vCi8vLyBJZiB0aGUgYGNlbGxgIGlzIGBudWxsYCwgb25seSBz' +
- 'dG9yZXMgMCBhcyBhIHNpbmdsZSBiaXQgaW50byB0aGUgY29weSBvZiB0aGUgYEJ1aWxkZXJgLiBSZXR1cm5zIHRoYXQgY29weS4KLy8vCi8vLyBBcyBhIHNpbmdsZSBg' +
- 'Q2VsbGAgY2FuIHN0b3JlIHVwIHRvIDQgcmVmZXJlbmNlcywgYXR0ZW1wdHMgdG8gc3RvcmUgbW9yZSB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBleGl0IGNvZGUgODog' +
- 'YENlbGwgb3ZlcmZsb3dgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGxldCBiOiBCdWlsZGVyID0gYmVnaW5DZWxsKCk7Ci8vLyBsZXQgZml6ejogQnVpbGRlciA9IGIKLy8v' +
- 'ICAgICAuc3RvcmVNYXliZVJlZihlbXB0eUNlbGwoKSkgLy8gMSwgdGhlbiBlbXB0eSBjZWxsCi8vLyAgICAgLnN0b3JlTWF5YmVSZWYobnVsbCk7ICAgICAgIC8vIDAK' +
- 'Ly8vIGBgYAovLy8KLy8vIEBzaW5jZSBUYWN0IDEuNS4wCi8vLyBAc2VlIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI2J1aWxkZXJzdG9y' +
- 'ZW1heWJlcmVmCi8vLwphc20oY2VsbCBzZWxmKSBleHRlbmRzIGZ1biBzdG9yZU1heWJlUmVmKHNlbGY6IEJ1aWxkZXIsIGNlbGw6IENlbGw/KTogQnVpbGRlciB7IFNU' +
- 'T1BUUkVGIH0KCmFzbSBleHRlbmRzIGZ1biBlbmRDZWxsKHNlbGY6IEJ1aWxkZXIpOiBDZWxsIHsgRU5EQyB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmcyhzZWxmOiBCdWls' +
- 'ZGVyKTogSW50IHsgQlJFRlMgfQoKYXNtIGV4dGVuZHMgZnVuIGJpdHMoc2VsZjogQnVpbGRlcik6IEludCB7IEJCSVRTIH0KCi8vCi8vIFNsaWNlCi8vCgphc20gZXh0' +
- 'ZW5kcyBmdW4gYmVnaW5QYXJzZShzZWxmOiBDZWxsKTogU2xpY2UgeyBDVE9TIH0KCmFzbSgtPiAxIDApIGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZFJlZihzZWxmOiBT' +
- 'bGljZSk6IENlbGwgeyBMRFJFRiB9CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYC4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwov' +
- 'Ly8gUHJlbG9hZHMgdGhlIG5leHQgcmVmZXJlbmNlIGZyb20gdGhlIGBTbGljZWAgYXMgYSBgQ2VsbGAuIERvZXNuJ3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBgU2xpY2Vg' +
- 'LgovLy8KLy8vIEF0dGVtcHRzIHRvIHByZWxvYWQgc3VjaCByZWZlcmVuY2UgYENlbGxgIHdoZW4gYFNsaWNlYCBkb2Vzbid0IGNvbnRhaW4gaXQgdGhyb3cgYW4gZXhj' +
- 'ZXB0aW9uIHdpdGggZXhpdCBjb2RlIDg6IGBDZWxsIG92ZXJmbG93YC4KLy8vCi8vLyBBdHRlbXB0cyB0byBwcmVsb2FkIG1vcmUgZGF0YSB0aGFuIGBTbGljZWAgY29u' +
- 'dGFpbnMgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDk6IGBDZWxsIHVuZGVyZmxvd2AuCi8vLwovLy8gYGBgdGFjdAovLy8gbGV0IHMxOiBTbGljZSA9' +
- 'IGJlZ2luQ2VsbCgpLnN0b3JlUmVmKGVtcHR5Q2VsbCgpKS5hc1NsaWNlKCk7Ci8vLyBsZXQgZml6ejogQ2VsbCA9IHMxLnByZWxvYWRSZWYoKTsgLy8gZGlkbid0IG1v' +
- 'ZGlmeSBzMQovLy8KLy8vIGxldCBzMjogU2xpY2UgPSBiZWdpbkNlbGwoKQovLy8gICAgIC5zdG9yZVJlZihlbXB0eUNlbGwoKSkKLy8vICAgICAuc3RvcmVSZWYoczEu' +
- 'YXNDZWxsKCkpCi8vLyAgICAgLmFzU2xpY2UoKTsKLy8vIGxldCByZWYxOiBDZWxsID0gczIucHJlbG9hZFJlZigpOwovLy8gbGV0IHJlZjI6IENlbGwgPSBzMi5wcmVs' +
- 'b2FkUmVmKCk7Ci8vLyByZWYxID09IHJlZjI7IC8vIHRydWUKLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2Nv' +
- 'cmUtY2VsbHMjc2xpY2VwcmVsb2FkcmVmCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2svZXhpdC1jb2RlcwovLy8KYXNtIGV4dGVuZHMgZnVuIHBy' +
- 'ZWxvYWRSZWYoc2VsZjogU2xpY2UpOiBDZWxsIHsgUExEUkVGIH0KCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3' +
- 'aXRoIGFzbSAiTERTTElDRVgiCkBuYW1lKGxvYWRfYml0cykKZXh0ZW5kcyBtdXRhdGVzIG5hdGl2ZSBsb2FkQml0cyhzZWxmOiBTbGljZSwgbDogSW50KTogU2xpY2U7' +
- 'CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIlBMRFNMSUNFWCIKQG5hbWUocHJlbG9hZF9iaXRz' +
- 'KQpleHRlbmRzIG5hdGl2ZSBwcmVsb2FkQml0cyhzZWxmOiBTbGljZSwgbDogSW50KTogU2xpY2U7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVy' +
- 'LCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIkxESVgiCkBuYW1lKGxvYWRfaW50KQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRJbnQoc2VsZjogU2xpY2UsIGw6' +
- 'IEludCk6IEludDsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiUExESVgiCkBuYW1lKHByZWxv' +
- 'YWRfaW50KQpleHRlbmRzIG5hdGl2ZSBwcmVsb2FkSW50KHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBJbnQ7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBp' +
- 'bGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIkxEVVgiCkBuYW1lKGxvYWRfdWludCkKZXh0ZW5kcyBtdXRhdGVzIG5hdGl2ZSBsb2FkVWludChzZWxmOiBTbGlj' +
- 'ZSwgbDogSW50KTogSW50OwoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90IHJlcGxhY2VkIHdpdGggYXNtICJQTERVWCIKQG5hbWUo' +
- 'cHJlbG9hZF91aW50KQpleHRlbmRzIG5hdGl2ZSBwcmVsb2FkVWludChzZWxmOiBTbGljZSwgbDogSW50KTogSW50OwoKYXNtKC0+IDEgMCkgZXh0ZW5kcyBtdXRhdGVz' +
- 'IGZ1biBsb2FkQm9vbChzZWxmOiBTbGljZSk6IEJvb2wgeyAxIExESSB9CgovLy8gRXh0ZW5zaW9uIG11dGF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYC4gQWxp' +
- 'YXMgdG8gYFNsaWNlLmxvYWRCb29sKClgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGxldCBzOiBTbGljZSA9IGJlZ2luQ2VsbCgpLnN0b3JlQm9vbCh0cnVlKS5hc1NsaWNl' +
- 'KCk7Ci8vLyBsZXQgZml6ejogQm9vbCA9IHMubG9hZEJpdCgpOyAvLyB0cnVlCi8vLyBgYGAKLy8vCi8vLyBAc2luY2UgVGFjdCAxLjUuMAovLy8gQHNlZSBodHRwczov' +
- 'L2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jZWxscyNzbGljZWxvYWRiaXQKLy8vCmFzbSgtPiAxIDApIGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZEJpdChzZWxm' +
- 'OiBTbGljZSk6IEJvb2wgeyAxIExESSB9Cgphc20oIC0+IDEgMCkgZXh0ZW5kcyBtdXRhdGVzIGZ1biBsb2FkQ29pbnMoc2VsZjogU2xpY2UpOiBJbnQgeyBMRFZBUlVJ' +
- 'TlQxNiB9CgpAbmFtZShfX3RhY3RfbG9hZF9hZGRyZXNzKQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRBZGRyZXNzKHNlbGY6IFNsaWNlKTogQWRkcmVzczsKCmFz' +
- 'bSBleHRlbmRzIG11dGF0ZXMgZnVuIHNraXBCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpIHsgU0RTS0lQRklSU1QgfQoKYXNtIGV4dGVuZHMgZnVuIGVuZFBhcnNlKHNl' +
- 'bGY6IFNsaWNlKSB7IEVORFMgfQoKLy8KLy8gU2xpY2Ugc2l6ZQovLwoKYXNtIGV4dGVuZHMgZnVuIHJlZnMoc2VsZjogU2xpY2UpOiBJbnQgeyBTUkVGUyB9Cgphc20g' +
- 'ZXh0ZW5kcyBmdW4gYml0cyhzZWxmOiBTbGljZSk6IEludCB7IFNCSVRTIH0KCmFzbSBleHRlbmRzIGZ1biBlbXB0eShzZWxmOiBTbGljZSk6IEJvb2wgeyBTRU1QVFkg' +
- 'fQoKYXNtIGV4dGVuZHMgZnVuIGRhdGFFbXB0eShzZWxmOiBTbGljZSk6IEJvb2wgeyBTREVNUFRZIH0KCmFzbSBleHRlbmRzIGZ1biByZWZzRW1wdHkoc2VsZjogU2xp' +
- 'Y2UpOiBCb29sIHsgU1JFTVBUWSB9CgovLwovLyBDb252ZXJzaW9ucwovLwoKaW5saW5lIGV4dGVuZHMgZnVuIGFzU2xpY2Uoc2VsZjogQnVpbGRlcik6IFNsaWNlIHsK' +
- 'ICAgIHJldHVybiBzZWxmLmVuZENlbGwoKS5iZWdpblBhcnNlKCk7Cn0KCmlubGluZSBleHRlbmRzIGZ1biBhc1NsaWNlKHNlbGY6IENlbGwpOiBTbGljZSB7CiAgICBy' +
- 'ZXR1cm4gc2VsZi5iZWdpblBhcnNlKCk7Cn0KCmlubGluZSBleHRlbmRzIGZ1biBhc0NlbGwoc2VsZjogU2xpY2UpOiBDZWxsIHsKICAgIHJldHVybiBiZWdpbkNlbGwo' +
- 'KQogICAgICAgIC5zdG9yZVNsaWNlKHNlbGYpCiAgICAgICAgLmVuZENlbGwoKTsKfQoKaW5saW5lIGV4dGVuZHMgZnVuIGFzQ2VsbChzZWxmOiBCdWlsZGVyKTogQ2Vs' +
- 'bCB7CiAgICByZXR1cm4gc2VsZi5lbmRDZWxsKCk7Cn0KCmlubGluZSBmdW4gZW1wdHlDZWxsKCk6IENlbGwgewogICAgcmV0dXJuIGJlZ2luQ2VsbCgpLmVuZENlbGwo' +
- 'KTsKfQoKaW5saW5lIGZ1biBlbXB0eVNsaWNlKCk6IFNsaWNlIHsKICAgIHJldHVybiBlbXB0eUNlbGwoKS5hc1NsaWNlKCk7Cn0K';
+ 'aW9uIGZ1bmN0aW9uIGZvciB0aGUgYEJ1aWxkZXJgLiBBbGlhcyB0byBgQnVpbGRlci5zdG9yZUJvb2woKWAuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8K' +
+ 'Ly8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBiOiBCdWlsZGVyID0gYmVnaW5DZWxsKCk7Ci8vLyAgICAgbGV0IGZpeno6IEJ1aWxkZXIg' +
+ 'PSBiLnN0b3JlQml0KHRydWUpOyAgLy8gd3JpdGVzIDEKLy8vICAgICBsZXQgYnV6ejogQnVpbGRlciA9IGIuc3RvcmVCaXQoZmFsc2UpOyAvLyB3cml0ZXMgMAovLy8g' +
+ 'fQovLy8gYGBgCi8vLwovLy8gU2VlOiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1jZWxscyNidWlsZGVyc3RvcmViaXQKLy8vCkBuYW1lKF9fdGFj' +
+ 'dF9zdG9yZV9ib29sKQpleHRlbmRzIG5hdGl2ZSBzdG9yZUJpdChzZWxmOiBCdWlsZGVyLCB2YWx1ZTogQm9vbCk6IEJ1aWxkZXI7Cgphc20gZXh0ZW5kcyBmdW4gc3Rv' +
+ 'cmVDb2lucyhzZWxmOiBCdWlsZGVyLCB2YWx1ZTogSW50KTogQnVpbGRlciB7IFNUVkFSVUlOVDE2IH0KCmFzbShjZWxsIHNlbGYpIGV4dGVuZHMgZnVuIHN0b3JlUmVm' +
+ 'KHNlbGY6IEJ1aWxkZXIsIGNlbGw6IENlbGwpOiBCdWlsZGVyIHsgU1RSRUYgfQoKYXNtIGV4dGVuZHMgZnVuIHN0b3JlU2xpY2Uoc2VsZjogQnVpbGRlciwgY2VsbDog' +
+ 'U2xpY2UpOiBCdWlsZGVyIHsgU1RTTElDRVIgfQoKLy8vIEV4dGVuc2lvbiBmdW5jdGlvbiBmb3IgdGhlIGBCdWlsZGVyYC4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41' +
+ 'LjAuCi8vLwovLy8gQXBwZW5kcyBhbGwgZGF0YSBmcm9tIGEgYEJ1aWxkZXJgIGBjZWxsYCB0byB0aGUgY29weSBvZiB0aGUgYEJ1aWxkZXJgLiBSZXR1cm5zIHRoYXQg' +
+ 'Y29weS4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgYjogQnVpbGRlciA9IGJlZ2luQ2VsbCgpLnN0b3JlQ29pbnMoNDIpOwov' +
+ 'Ly8gICAgIGxldCBmaXp6OiBCdWlsZGVyID0gYmVnaW5DZWxsKCkuc3RvcmVCdWlsZGVyKGIpOwovLy8gICAgIGIuZW5kQ2VsbCgpID09IGZpenouZW5kQ2VsbCgpOyAv' +
+ 'LyB0cnVlCi8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI2J1aWxkZXJzdG9yZWJ1aWxkZXIK' +
+ 'Ly8vCmFzbSBleHRlbmRzIGZ1biBzdG9yZUJ1aWxkZXIoc2VsZjogQnVpbGRlciwgY2VsbDogQnVpbGRlcik6IEJ1aWxkZXIgeyBTVEJSIH0KCkBuYW1lKF9fdGFjdF9z' +
+ 'dG9yZV9hZGRyZXNzKQpleHRlbmRzIG5hdGl2ZSBzdG9yZUFkZHJlc3Moc2VsZjogQnVpbGRlciwgYWRkcmVzczogQWRkcmVzcyk6IEJ1aWxkZXI7CgovLy8gRXh0ZW5z' +
+ 'aW9uIGZ1bmN0aW9uIGZvciB0aGUgYEJ1aWxkZXJgLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBJZiB0aGUgYGNlbGxgIGlzIG5vdCBgbnVsbGAs' +
+ 'IHN0b3JlcyAxIGFzIGEgc2luZ2xlIGJpdCBhbmQgdGhlbiByZWZlcmVuY2UgYGNlbGxgIGludG8gdGhlIGNvcHkgb2YgdGhlIGBCdWlsZGVyYC4gUmV0dXJucyB0aGF0' +
+ 'IGNvcHkuCi8vLwovLy8gSWYgdGhlIGBjZWxsYCBpcyBgbnVsbGAsIG9ubHkgc3RvcmVzIDAgYXMgYSBzaW5nbGUgYml0IGludG8gdGhlIGNvcHkgb2YgdGhlIGBCdWls' +
+ 'ZGVyYC4gUmV0dXJucyB0aGF0IGNvcHkuCi8vLwovLy8gQXMgYSBzaW5nbGUgYENlbGxgIGNhbiBzdG9yZSB1cCB0byA0IHJlZmVyZW5jZXMsIGF0dGVtcHRzIHRvIHN0' +
+ 'b3JlIG1vcmUgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDg6IGBDZWxsIG92ZXJmbG93YC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgp' +
+ 'IHsKLy8vICAgICBsZXQgYjogQnVpbGRlciA9IGJlZ2luQ2VsbCgpOwovLy8gICAgIGxldCBmaXp6OiBCdWlsZGVyID0gYgovLy8gICAgICAgICAuc3RvcmVNYXliZVJl' +
+ 'ZihlbXB0eUNlbGwoKSkgLy8gMSwgdGhlbiBlbXB0eSBjZWxsCi8vLyAgICAgICAgIC5zdG9yZU1heWJlUmVmKG51bGwpOyAgICAgICAvLyAwCi8vLyB9Ci8vLyBgYGAK' +
+ 'Ly8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI2J1aWxkZXJzdG9yZW1heWJlcmVmCi8vLwphc20oY2VsbCBzZWxmKSBl' +
+ 'eHRlbmRzIGZ1biBzdG9yZU1heWJlUmVmKHNlbGY6IEJ1aWxkZXIsIGNlbGw6IENlbGw/KTogQnVpbGRlciB7IFNUT1BUUkVGIH0KCmFzbSBleHRlbmRzIGZ1biBlbmRD' +
+ 'ZWxsKHNlbGY6IEJ1aWxkZXIpOiBDZWxsIHsgRU5EQyB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmcyhzZWxmOiBCdWlsZGVyKTogSW50IHsgQlJFRlMgfQoKYXNtIGV4dGVu' +
+ 'ZHMgZnVuIGJpdHMoc2VsZjogQnVpbGRlcik6IEludCB7IEJCSVRTIH0KCi8vCi8vIFNsaWNlCi8vCgphc20gZXh0ZW5kcyBmdW4gYmVnaW5QYXJzZShzZWxmOiBDZWxs' +
+ 'KTogU2xpY2UgeyBDVE9TIH0KCmFzbSgtPiAxIDApIGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZFJlZihzZWxmOiBTbGljZSk6IENlbGwgeyBMRFJFRiB9CgovLy8gRXh0' +
+ 'ZW5zaW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYC4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gUHJlbG9hZHMgdGhlIG5leHQgcmVmZXJlbmNl' +
+ 'IGZyb20gdGhlIGBTbGljZWAgYXMgYSBgQ2VsbGAuIERvZXNuJ3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBgU2xpY2VgLgovLy8KLy8vIEF0dGVtcHRzIHRvIHByZWxvYWQg' +
+ 'c3VjaCByZWZlcmVuY2UgYENlbGxgIHdoZW4gYFNsaWNlYCBkb2Vzbid0IGNvbnRhaW4gaXQgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDg6IGBDZWxs' +
+ 'IG92ZXJmbG93YC4KLy8vCi8vLyBBdHRlbXB0cyB0byBwcmVsb2FkIG1vcmUgZGF0YSB0aGFuIGBTbGljZWAgY29udGFpbnMgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGgg' +
+ 'ZXhpdCBjb2RlIDk6IGBDZWxsIHVuZGVyZmxvd2AuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGVzKCkgewovLy8gICAgIGxldCBzMTogU2xpY2UgPSBiZWdp' +
+ 'bkNlbGwoKS5zdG9yZVJlZihlbXB0eUNlbGwoKSkuYXNTbGljZSgpOwovLy8gICAgIGxldCBmaXp6OiBDZWxsID0gczEucHJlbG9hZFJlZigpOyAvLyBkaWRuJ3QgbW9k' +
+ 'aWZ5IHMxCi8vLwovLy8gICAgIGxldCBzMjogU2xpY2UgPSBiZWdpbkNlbGwoKQovLy8gICAgICAgICAuc3RvcmVSZWYoZW1wdHlDZWxsKCkpCi8vLyAgICAgICAgIC5z' +
+ 'dG9yZVJlZihzMS5hc0NlbGwoKSkKLy8vICAgICAgICAgLmFzU2xpY2UoKTsKLy8vICAgICBsZXQgcmVmMTogQ2VsbCA9IHMyLnByZWxvYWRSZWYoKTsKLy8vICAgICBs' +
+ 'ZXQgcmVmMjogQ2VsbCA9IHMyLnByZWxvYWRSZWYoKTsKLy8vICAgICByZWYxID09IHJlZjI7IC8vIHRydWUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICog' +
+ 'aHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtY2VsbHMjc2xpY2VwcmVsb2FkcmVmCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL2Jvb2sv' +
+ 'ZXhpdC1jb2RlcwovLy8KYXNtIGV4dGVuZHMgZnVuIHByZWxvYWRSZWYoc2VsZjogU2xpY2UpOiBDZWxsIHsgUExEUkVGIH0KCi8vIHNwZWNpYWwgdHJlYXRtZW50IGlu' +
+ 'IEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiTERTTElDRVgiCkBuYW1lKGxvYWRfYml0cykKZXh0ZW5kcyBtdXRhdGVzIG5hdGl2ZSBsb2Fk' +
+ 'Qml0cyhzZWxmOiBTbGljZSwgbDogSW50KTogU2xpY2U7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBh' +
+ 'c20gIlBMRFNMSUNFWCIKQG5hbWUocHJlbG9hZF9iaXRzKQpleHRlbmRzIG5hdGl2ZSBwcmVsb2FkQml0cyhzZWxmOiBTbGljZSwgbDogSW50KTogU2xpY2U7CgovLyBz' +
+ 'cGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIkxESVgiCkBuYW1lKGxvYWRfaW50KQpleHRlbmRzIG11dGF0' +
+ 'ZXMgbmF0aXZlIGxvYWRJbnQoc2VsZjogU2xpY2UsIGw6IEludCk6IEludDsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBs' +
+ 'YWNlZCB3aXRoIGFzbSAiUExESVgiCkBuYW1lKHByZWxvYWRfaW50KQpleHRlbmRzIG5hdGl2ZSBwcmVsb2FkSW50KHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBJbnQ7Cgov' +
+ 'LyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIkxEVVgiCkBuYW1lKGxvYWRfdWludCkKZXh0ZW5kcyBt' +
+ 'dXRhdGVzIG5hdGl2ZSBsb2FkVWludChzZWxmOiBTbGljZSwgbDogSW50KTogSW50OwoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90' +
+ 'IHJlcGxhY2VkIHdpdGggYXNtICJQTERVWCIKQG5hbWUocHJlbG9hZF91aW50KQpleHRlbmRzIG5hdGl2ZSBwcmVsb2FkVWludChzZWxmOiBTbGljZSwgbDogSW50KTog' +
+ 'SW50OwoKYXNtKC0+IDEgMCkgZXh0ZW5kcyBtdXRhdGVzIGZ1biBsb2FkQm9vbChzZWxmOiBTbGljZSk6IEJvb2wgeyAxIExESSB9CgovLy8gRXh0ZW5zaW9uIG11dGF0' +
+ 'aW9uIGZ1bmN0aW9uIGZvciB0aGUgYFNsaWNlYC4gQWxpYXMgdG8gYFNsaWNlLmxvYWRCb29sKClgLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBg' +
+ 'YGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgczogU2xpY2UgPSBiZWdpbkNlbGwoKS5zdG9yZUJvb2wodHJ1ZSkuYXNTbGljZSgpOwovLy8gICAg' +
+ 'IGxldCBmaXp6OiBCb29sID0gcy5sb2FkQml0KCk7IC8vIHRydWUKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVm' +
+ 'L2NvcmUtY2VsbHMjc2xpY2Vsb2FkYml0Ci8vLwphc20oLT4gMSAwKSBleHRlbmRzIG11dGF0ZXMgZnVuIGxvYWRCaXQoc2VsZjogU2xpY2UpOiBCb29sIHsgMSBMREkg' +
+ 'fQoKYXNtKCAtPiAxIDApIGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZENvaW5zKHNlbGY6IFNsaWNlKTogSW50IHsgTERWQVJVSU5UMTYgfQoKQG5hbWUoX190YWN0X2xv' +
+ 'YWRfYWRkcmVzcykKZXh0ZW5kcyBtdXRhdGVzIG5hdGl2ZSBsb2FkQWRkcmVzcyhzZWxmOiBTbGljZSk6IEFkZHJlc3M7Cgphc20gZXh0ZW5kcyBtdXRhdGVzIGZ1biBz' +
+ 'a2lwQml0cyhzZWxmOiBTbGljZSwgbDogSW50KSB7IFNEU0tJUEZJUlNUIH0KCmFzbSBleHRlbmRzIGZ1biBlbmRQYXJzZShzZWxmOiBTbGljZSkgeyBFTkRTIH0KCi8v' +
+ 'Ci8vIFNsaWNlIHNpemUKLy8KCmFzbSBleHRlbmRzIGZ1biByZWZzKHNlbGY6IFNsaWNlKTogSW50IHsgU1JFRlMgfQoKYXNtIGV4dGVuZHMgZnVuIGJpdHMoc2VsZjog' +
+ 'U2xpY2UpOiBJbnQgeyBTQklUUyB9Cgphc20gZXh0ZW5kcyBmdW4gZW1wdHkoc2VsZjogU2xpY2UpOiBCb29sIHsgU0VNUFRZIH0KCmFzbSBleHRlbmRzIGZ1biBkYXRh' +
+ 'RW1wdHkoc2VsZjogU2xpY2UpOiBCb29sIHsgU0RFTVBUWSB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmc0VtcHR5KHNlbGY6IFNsaWNlKTogQm9vbCB7IFNSRU1QVFkgfQoK' +
+ 'Ly8KLy8gQ29udmVyc2lvbnMKLy8KCmlubGluZSBleHRlbmRzIGZ1biBhc1NsaWNlKHNlbGY6IEJ1aWxkZXIpOiBTbGljZSB7CiAgICByZXR1cm4gc2VsZi5lbmRDZWxs' +
+ 'KCkuYmVnaW5QYXJzZSgpOwp9CgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNTbGljZShzZWxmOiBDZWxsKTogU2xpY2UgewogICAgcmV0dXJuIHNlbGYuYmVnaW5QYXJzZSgp' +
+ 'Owp9CgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNDZWxsKHNlbGY6IFNsaWNlKTogQ2VsbCB7CiAgICByZXR1cm4gYmVnaW5DZWxsKCkKICAgICAgICAuc3RvcmVTbGljZShz' +
+ 'ZWxmKQogICAgICAgIC5lbmRDZWxsKCk7Cn0KCmlubGluZSBleHRlbmRzIGZ1biBhc0NlbGwoc2VsZjogQnVpbGRlcik6IENlbGwgewogICAgcmV0dXJuIHNlbGYuZW5k' +
+ 'Q2VsbCgpOwp9CgppbmxpbmUgZnVuIGVtcHR5Q2VsbCgpOiBDZWxsIHsKICAgIHJldHVybiBiZWdpbkNlbGwoKS5lbmRDZWxsKCk7Cn0KCmlubGluZSBmdW4gZW1wdHlT' +
+ 'bGljZSgpOiBTbGljZSB7CiAgICByZXR1cm4gZW1wdHlDZWxsKCkuYXNTbGljZSgpOwp9Cg==';
files['std/config.tact'] =
'YXNtIGZ1biBnZXRDb25maWdQYXJhbShpZDogSW50KTogQ2VsbD8geyBDT05GSUdPUFRQQVJBTSB9Cg==';
files['std/context.tact'] =
@@ -199,54 +206,121 @@ files['std/contract.tact'] =
'KHM6IFN0YXRlSW5pdCk6IEFkZHJlc3MgewogICAgcmV0dXJuIGNvbnRyYWN0QWRkcmVzc0V4dCgwLCBzLmNvZGUsIHMuZGF0YSk7Cn0KCkBuYW1lKF9fdGFjdF9hZGRy' +
'ZXNzX3RvX3NsaWNlKQpleHRlbmRzIG5hdGl2ZSBhc1NsaWNlKHNlbGY6IEFkZHJlc3MpOiBTbGljZTsKCkBuYW1lKF9fdGFjdF9jcmVhdGVfYWRkcmVzcykKbmF0aXZl' +
'IG5ld0FkZHJlc3MoY2hhaW46IEludCwgaGFzaDogSW50KTogQWRkcmVzczsKCmFzbSBmdW4gbXlBZGRyZXNzKCk6IEFkZHJlc3MgeyBNWUFERFIgfQoKYXNtIGZ1biBt' +
- 'eUJhbGFuY2UoKTogSW50IHsgQkFMQU5DRSBGSVJTVCB9CgovLyBSZXR1cm5zIGdhcyBjb25zdW1lZCBieSBWTSBzbyBmYXIgKGluY2x1ZGluZyB0aGlzIGluc3RydWN0' +
- 'aW9uKS4KYXNtIGZ1biBnYXNDb25zdW1lZCgpOiBJbnQgeyBHQVNDT05TVU1FRCB9CgovLyBDYWxjdWxhdGVzIGNvbXB1dGF0aW9uIGNvc3QgaW4gbmFub3RvbnMgZm9y' +
- 'IHRyYW5zYWN0aW9uIHRoYXQgY29uc3VtZXMgYGdhc191c2VkYCBnYXMuCmFzbSBmdW4gZ2V0Q29tcHV0ZUZlZShnYXNfdXNlZDogSW50LCBpc19tYXN0ZXJjaGFpbjog' +
- 'Qm9vbCk6IEludCB7IEdFVEdBU0ZFRSB9CgovLyBDYWxjdWxhdGVzIHN0b3JhZ2UgZmVlcyBpbiBuYW5vdG9ucyBmb3IgY29udHJhY3QgYmFzZWQgb24gY3VycmVudCBz' +
- 'dG9yYWdlIHByaWNlcy4gYGNlbGxzYCBhbmQgYGJpdHNgIGFyZSB0aGUgc2l6ZSBvZiB0aGUgQWNjb3VudFN0YXRlICh3aXRoIGRlZHVwbGljYXRpb24sIGluY2x1ZGlu' +
- 'ZyByb290IGNlbGwpLgphc20gZnVuIGdldFN0b3JhZ2VGZWUoY2VsbHM6IEludCwgYml0czogSW50LCBzZWNvbmRzOiBJbnQsIGlzX21hc3RlcmNoYWluOiBCb29sKTog' +
- 'SW50IHsgR0VUU1RPUkFHRUZFRSB9CgovLyBDYWxjdWxhdGVzIGZvcndhcmQgZmVlcyBpbiBuYW5vdG9ucyBmb3Igb3V0Z29pbmcgbWVzc2FnZS4gYGlzX21hc3RlcmNo' +
- 'YWluYCBpcyB0cnVlIGlmIHRoZSBzb3VyY2Ugb3IgdGhlIGRlc3RpbmF0aW9uIGlzIGluIG1hc3RlcmNoYWluLCBmYWxzZSBpZiBib3RoIGFyZSBpbiBiYXNlY2hhaW4u' +
- 'IE5vdGUsIGBjZWxsc2AgYW5kIGBiaXRzYCBpbiBNZXNzYWdlIHNob3VsZCBiZSBjb3VudGVkIHdpdGggYWNjb3VudCBmb3IgZGVkdXBsaWNhdGlvbiBhbmQgcm9vdC1p' +
- 'cy1ub3QtY291bnRlZCBydWxlcy4KYXNtIGZ1biBnZXRGb3J3YXJkRmVlKGNlbGxzOiBJbnQsIGJpdHM6IEludCwgaXNfbWFzdGVyY2hhaW46IEJvb2wpOiBJbnQgeyBH' +
- 'RVRGT1JXQVJERkVFIH0KCi8vIENhbGN1bGF0ZXMgYWRkaXRpb25hbCBjb21wdXRhdGlvbiBjb3N0IGluIG5hbm90b25zIGZvciB0cmFuc2FjdGlvbiB0aGF0IGNvbnN1' +
- 'bWVzIGFkZGl0aW9uYWwgYGdhc191c2VkYC4gSW4gb3RoZXIgd29yZHMsIHNhbWUgYXMgYGdldENvbXB1dGVGZWVgLCBidXQgd2l0aG91dCBmbGF0IHByaWNlIChqdXN0' +
- 'IGAoZ2FzX3VzZWQgKiBwcmljZSkgLyAyXjE2YCkuCmFzbSBmdW4gZ2V0U2ltcGxlQ29tcHV0ZUZlZShnYXNfdXNlZDogSW50LCBpc19tYXN0ZXJjaGFpbjogQm9vbCk6' +
- 'IEludCB7IEdFVEdBU0ZFRVNJTVBMRSB9CgovLyBDYWxjdWxhdGVzIGFkZGl0aW9uYWwgZm9yd2FyZCBjb3N0IGluIG5hbm90b25zIGZvciBtZXNzYWdlIHRoYXQgY29u' +
- 'dGFpbnMgYWRkaXRpb25hbCBgY2VsbHNgIGFuZCBgYml0c2AuIEluIG90aGVyIHdvcmRzLCBzYW1lIGFzIGBnZXRGb3J3YXJkRmVlYCwgYnV0IHdpdGhvdXQgbHVtcCBw' +
- 'cmljZSAoanVzdCBgKGJpdHMqYml0X3ByaWNlICsgY2VsbHMqY2VsbF9wcmljZSkgLyAyXjE2YCkuCmFzbSBmdW4gZ2V0U2ltcGxlRm9yd2FyZEZlZShjZWxsczogSW50' +
- 'LCBiaXRzOiBJbnQsIGlzX21hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VURk9SV0FSREZFRVNJTVBMRSB9CgovLyBDYWxjdWxhdGUgYGZ3ZF9mZWUgKiAyXjE2IC8g' +
- 'Zmlyc3RfZnJhY2AuIENhbiBiZSB1c2VkIHRvIGdldCB0aGUgb3JpZ2luYWwgYGZ3ZF9mZWVgIG9mIHRoZSBtZXNzYWdlIChhcyByZXBsYWNlbWVudCBmb3IgaGFyZGNv' +
- 'ZGVkIHZhbHVlcykgZnJvbSBgZndkX2ZlZWAgcGFyc2VkIGZyb20gaW5jb21pbmcgbWVzc2FnZS4gYGlzX21hc3RlcmNoYWluYCBpcyB0cnVlIGlmIHRoZSBzb3VyY2Ug' +
- 'b3IgdGhlIGRlc3RpbmF0aW9uIGlzIGluIG1hc3RlcmNoYWluLCBmYWxzZSBpZiBib3RoIGFyZSBpbiBiYXNlY2hhaW4uCmFzbSBmdW4gZ2V0T3JpZ2luYWxGd2RGZWUo' +
- 'ZndkX2ZlZTogSW50LCBpc19tYXN0ZXJjaGFpbjogQm9vbCk6IEludCB7IEdFVE9SSUdJTkFMRldERkVFIH0KCi8vIEN1cnJlbnQgZGVidCBmb3Igc3RvcmFnZSBmZWUg' +
- 'aW4gbmFub3RvbnMuCmFzbSBmdW4gbXlTdG9yYWdlRHVlKCk6IEludCB7IERVRVBBWU1FTlQgfQoKLy8vIFN0cnVjdCByZXByZXNlbnRpbmcgdGhlIHN0YW5kYXJkIGFk' +
- 'ZHJlc3Mgb24gVE9OIEJsb2NrY2hhaW4gd2l0aCBzaWduZWQgOC1iaXQgYHdvcmtjaGFpbmAgSUQgYW5kIGFuIHVuc2lnbmVkIDI1Ni1iaXQgYGFkZHJlc3NgIGluIHRo' +
- 'ZSBzcGVjaWZpZWQgYHdvcmtjaGFpbmAuCi8vLwovLy8gQXQgdGhlIG1vbWVudCwgb25seSBgd29ya2NoYWluYCBJRHMgdXNlZCBvbiBUT04gYXJlIDAgb2YgdGhlIGJh' +
- 'c2VjaGFpbiBhbmQgLTEgb2YgdGhlIG1hc3RlcmNoYWluLgovLy8KLy8vIEBzaW5jZSBUYWN0IDEuNS4wCi8vLyBAc2VlIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3Jn' +
- 'L3JlZi9jb3JlLWFkdmFuY2VkI3BhcnNlc3RkYWRkcmVzcwovLy8gQHNlZSBodHRwczovL2dpdGh1Yi5jb20vdG9uLWJsb2NrY2hhaW4vdG9uL2Jsb2IvbWFzdGVyL2Ny' +
- 'eXB0by9ibG9jay9ibG9jay50bGIjTDEwNS1MMTA2Ci8vLwpzdHJ1Y3QgU3RkQWRkcmVzcyB7CiAgICB3b3JrY2hhaW46IEludCBhcyBpbnQ4OwogICAgYWRkcmVzczog' +
- 'SW50IGFzIHVpbnQyNTY7Cn0KCi8vLyBTdHJ1Y3QgcmVwcmVzZW50aW5nIHRoZSBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCB3aXRoIHNpZ25lZCAzMi1iaXQgYHdv' +
- 'cmtjaGFpbmAgSUQgYW5kIGEgYFNsaWNlYCBjb250YWluaW5nIHVuc2lnbmVkIGBhZGRyZXNzYCBpbiB0aGUgc3BlY2lmaWVkIGB3b3JrY2hhaW5gLgovLy8KLy8vIFZh' +
- 'cmlhYmxlLWxlbmd0aCBhZGRyZXNzZXMgYXJlIGludGVuZGVkIGZvciBmdXR1cmUgZXh0ZW5zaW9ucywgYW5kIHdoaWxlIHZhbGlkYXRvcnMgbXVzdCBiZSByZWFkeSB0' +
- 'byBhY2NlcHQgdGhlbSBpbiBpbmJvdW5kIG1lc3NhZ2VzLCB0aGUgc3RhbmRhcmQgKG5vbi12YXJpYWJsZSkgYWRkcmVzc2VzIGFyZSB1c2VkIHdoZW5ldmVyIHBvc3Np' +
- 'YmxlLgovLy8KLy8vIEBzaW5jZSBUYWN0IDEuNS4wCi8vLyBAc2VlIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI3BhcnNldmFyYWRk' +
- 'cmVzcwovLy8gQHNlZSBodHRwczovL2dpdGh1Yi5jb20vdG9uLWJsb2NrY2hhaW4vdG9uL2Jsb2IvbWFzdGVyL2NyeXB0by9ibG9jay9ibG9jay50bGIjTDEwNy1MMTA4' +
- 'Ci8vLwpzdHJ1Y3QgVmFyQWRkcmVzcyB7CiAgICB3b3JrY2hhaW46IEludCBhcyBpbnQzMjsKICAgIGFkZHJlc3M6IFNsaWNlOwp9CgovLy8gQ29udmVydHMgYSBgU2xp' +
- 'Y2VgIGNvbnRhaW5pbmcgYW4gYWRkcmVzcyBpbnRvIHRoZSBgU3RkQWRkcmVzc2AgU3RydWN0IGFuZCByZXR1cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGxldCBh' +
- 'ZGRyID0gYWRkcmVzcygiRVFEdEZwRXdjRkFFY1JlNW1MVmgyTjZDMHgtX2hKRU03VzYxX0pMblNGNzRwNHEyIik7Ci8vLyBsZXQgcGFyc2VkQWRkciA9IHBhcnNlU3Rk' +
- 'QWRkcmVzcyhhZGRyLmFzU2xpY2UoKSk7Ci8vLwovLy8gcGFyc2VkQWRkci53b3JrY2hhaW47IC8vIDAKLy8vIHBhcnNlZEFkZHIuYWRkcmVzczsgICAvLyAxMDcuLi4y' +
- 'ODcKLy8vIGBgYAovLy8KLy8vIEBzaW5jZSBUYWN0IDEuNS4wCi8vLyBAc2VlIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI3BhcnNl' +
- 'c3RkYWRkcmVzcwovLy8KYXNtIGZ1biBwYXJzZVN0ZEFkZHJlc3Moc2xpY2U6IFNsaWNlKTogU3RkQWRkcmVzcyB7IFJFV1JJVEVTVERBRERSIH0KCi8vLyBDb252ZXJ0' +
- 'cyBhIGBTbGljZWAgY29udGFpbmluZyBhbiBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCBpbnRvIHRoZSBgVmFyQWRkcmVzc2AgU3RydWN0IGFuZCByZXR1cm5zIGl0' +
- 'LgovLy8KLy8vIGBgYHRhY3QKLy8vIGxldCB2YXJBZGRyU2xpY2UgPSBiZWdpbkNlbGwoKQovLy8gICAgIC5zdG9yZVVpbnQoNiwgMykgICAgIC8vIHRvIHJlY29nbml6' +
- 'ZSB0aGUgZm9sbG93aW5nIGFzIGEgVmFyQWRkcmVzcwovLy8gICAgIC5zdG9yZVVpbnQoMTIzLCA5KSAgIC8vIG1ha2UgYWRkcmVzcyBvY2N1cHkgMTIzIGJpdHMKLy8v' +
- 'ICAgICAuc3RvcmVVaW50KDIzNCwgMzIpICAvLyBzcGVjaWZ5IHdvcmtjaGFpbiBJRCBvZiAyMzQKLy8vICAgICAuc3RvcmVVaW50KDM0NSwgMTIzKSAvLyBzcGVjaWZ5' +
- 'IGFkZHJlc3Mgb2YgMzQ1Ci8vLyAgICAgLmFzU2xpY2UoKTsKLy8vIGxldCBwYXJzZWRWYXJBZGRyID0gcGFyc2VWYXJBZGRyZXNzKHZhckFkZHJTbGljZSk7Ci8vLwov' +
- 'Ly8gcGFyc2VkVmFyQWRkci53b3JrY2hhaW47ICAgICAgICAgICAgIC8vIDIzNAovLy8gcGFyc2VkVmFyQWRkci5hZGRyZXNzOyAgICAgICAgICAgICAgIC8vIENTe0Nl' +
- 'bGx7MDAyLi4uMmIzfSBiaXRzOiA0NC4uMTY3OyByZWZzOiAwLi4wfQovLy8gcGFyc2VkVmFyQWRkci5hZGRyZXNzLmxvYWRVaW50KDEyMyk7IC8vIDM0NQovLy8gYGBg' +
- 'Ci8vLwovLy8gQHNpbmNlIFRhY3QgMS41LjAKLy8vIEBzZWUgaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2V2YXJhZGRyZXNz' +
- 'Ci8vLwphc20gZnVuIHBhcnNlVmFyQWRkcmVzcyhzbGljZTogU2xpY2UpOiBWYXJBZGRyZXNzIHsgUkVXUklURVZBUkFERFIgfQo=';
+ 'eUJhbGFuY2UoKTogSW50IHsgQkFMQU5DRSBGSVJTVCB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBSZXR1' +
+ 'cm5zIHRoZSBuYW5vVG9uY29pbiBgSW50YCBhbW91bnQgb2YgZ2FzIGNvbnN1bWVkIGJ5IFRWTSBpbiB0aGUgY3VycmVudCB0cmFuc2FjdGlvbiBzbyBmYXIuIFRoZSBy' +
+ 'ZXN1bHRpbmcgdmFsdWUgaW5jbHVkZXMgdGhlIGNvc3Qgb2YgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewov' +
+ 'Ly8gICAgIGxldCBnYXM6IEludCA9IGdhc0NvbnN1bWVkKCk7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9j' +
+ 'b3JlLWFkdmFuY2VkI2dhc2NvbnN1bWVkCi8vLwphc20gZnVuIGdhc0NvbnN1bWVkKCk6IEludCB7IEdBU0NPTlNVTUVEIH0KCi8vLyBHbG9iYWwgZnVuY3Rpb24uIEF2' +
+ 'YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8vIFJldHVybnMgdGhlIG5hbm9Ub25jb2luIGBJbnRgIGFtb3VudCBvZiB0aGUgYWNjdW11bGF0ZWQgc3RvcmFn' +
+ 'ZSBmZWUgZGVidC4gU3RvcmFnZSBmZWVzIGFyZSBkZWR1Y3RlZCBmcm9tIHRoZSBpbmNvbWluZyBtZXNzYWdlIHZhbHVlIGJlZm9yZSB0aGUgbmV3IGNvbnRyYWN0IGJh' +
+ 'bGFuY2UgaXMgY2FsY3VsYXRlZC4KLy8vCi8vLyBgYGB0YWN0Ci8vLyBmdW4gZXhhbXBsZSgpIHsKLy8vICAgICBsZXQgZGVidDogSW50ID0gbXlTdG9yYWdlRHVlKCk7' +
+ 'Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6IGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI215c3RvcmFnZWR1ZQovLy8KYXNtIGZ1' +
+ 'biBteVN0b3JhZ2VEdWUoKTogSW50IHsgRFVFUEFZTUVOVCB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBD' +
+ 'YWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBzdG9yYWdlIGZlZSBpbiBuYW5vVG9uY29pbnMgYEludGAgZm9yIHN0b3JpbmcgYSBjb250cmFjdCB3aXRoIGEgZ2l2ZW4g' +
+ 'bnVtYmVyIG9mIGBjZWxsc2AgYW5kIGBiaXRzYCBmb3IgYSBudW1iZXIgb2YgYHNlY29uZHNgLiBVc2VzIHRoZSBwcmljZXMgb2YgdGhlIG1hc3RlcmNoYWluIGlmIGBp' +
+ 'c01hc3RlcmNoYWluYCBpcyBgdHJ1ZWAsIG90aGVyd2lzZSB0aGUgcHJpY2VzIG9mIHRoZSBiYXNlY2hhaW4uIFRoZSBjdXJyZW50IHByaWNlcyBhcmUgb2J0YWluZWQg' +
+ 'ZnJvbSB0aGUgY29uZmlnIHBhcmFtIDE4IG9mIFRPTiBCbG9ja2NoYWluLgovLy8KLy8vIE5vdGUsIHRoYXQgdGhlIHZhbHVlcyBvZiBgY2VsbHNgIGFuZCBgYml0c2Ag' +
+ 'YXJlIHRha2VuIG1vZHVsbyB0aGVpciBtYXhpbXVtIHZhbHVlcyBwbHVzIDEuIFRoYXQgaXMsIHNwZWNpZnlpbmcgdmFsdWVzIGhpZ2hlciB0aGFuIHRob3NlIGxpc3Rl' +
+ 'ZCBpbiBhY2NvdW50IHN0YXRlIGxpbWl0cyAoYG1heF9hY2Nfc3RhdGVfY2VsbHNgIGFuZCBgbWF4X2FjY19zdGF0ZV9iaXRzYCkgd2lsbCBoYXZlIHRoZSBzYW1lIHJl' +
+ 'c3VsdCBhcyB3aXRoIHNwZWNpZnlpbmcgdGhlIGV4YWN0IGxpbWl0cy4gSW4gYWRkaXRpb24sIG1ha2Ugc3VyZSB5b3UgdGFrZSBpbnRvIGFjY291bnQgdGhlIGRlZHVw' +
+ 'bGljYXRpb24gb2YgY2VsbHMgd2l0aCB0aGUgc2FtZSBoYXNoLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2AsIGBi' +
+ 'aXRzYCBvciBgc2Vjb25kc2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwovLy8g' +
+ 'YGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZTogSW50ID0gZ2V0U3RvcmFnZUZlZSgxXzAwMCwgMV8wMDAsIDFfMDAwLCBmYWxzZSk7Ci8v' +
+ 'LyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHN0b3JhZ2VmZWUKLy8vICog' +
+ 'aHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0c2ltcGxlc3RvcmFnZWZlZQovLy8KYXNtIGZ1biBnZXRTdG9yYWdlRmVlKGNlbGxz' +
+ 'OiBJbnQsIGJpdHM6IEludCwgc2Vjb25kczogSW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VUU1RPUkFHRUZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9u' +
+ 'LiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBjb21wdXRlIGZlZSBpbiBuYW5vVG9uY29pbnMgYElu' +
+ 'dGAgZm9yIGEgdHJhbnNhY3Rpb24gdGhhdCBjb25zdW1lZCBgZ2FzVXNlZGAgYW1vdW50IG9mIGdhcy4gVXNlcyB0aGUgcHJpY2VzIG9mIHRoZSBtYXN0ZXJjaGFpbiBp' +
+ 'ZiBgaXNNYXN0ZXJjaGFpbmAgaXMgYHRydWVgLCBvdGhlcndpc2UgdGhlIHByaWNlcyBvZiB0aGUgYmFzZWNoYWluLiBUaGUgY3VycmVudCBwcmljZXMgYXJlIG9idGFp' +
+ 'bmVkIGZyb20gdGhlIGNvbmZpZyBwYXJhbSAyMCBmb3IgdGhlIG1hc3RlcmNoYWluIGFuZCBjb25maWcgcGFyYW0gMjEgZm9yIHRoZSBiYXNlY2hhaW4gb2YgVE9OIEJs' +
+ 'b2NrY2hhaW4uCi8vLwovLy8gV2hlbiB0aGUgYGdhc1VzZWRgIGlzIGxlc3MgdGhhbiBhIGNlcnRhaW4gdGhyZXNob2xkIGNhbGxlZCBgZmxhdF9nYXNfbGltaXRgLCB0' +
+ 'aGVyZSdzIGEgbWluaW11bSBwcmljZSB0byBwYXkgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGBmbGF0X2dhc19wcmljZWAuIFRoZSBsZXNzIGdhcyBpcyB1c2VkIGJlbG93' +
+ 'IHRoaXMgdGhyZXNob2xkLCB0aGUgaGlnaGVyIHRoZSBtaW5pbXVtIHByaWNlIHdpbGwgYmUuIFNlZSB0aGUgZXhhbXBsZSBmb3IgYGdldFNpbXBsZUNvbXB1dGVGZWUo' +
+ 'KWAgdG8gZGVyaXZlIHRoYXQgdGhyZXNob2xkLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgdmFsdWUgb2YgYGdhc1VzZWRgIHRocm93IGFuIGV4' +
+ 'Y2VwdGlvbiB3aXRoIGV4aXQgY29kZSA1OiBgSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewov' +
+ 'Ly8gICAgIGxldCBmZWU6IEludCA9IGdldENvbXB1dGVGZWUoMV8wMDAsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3Qt' +
+ 'bGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Y29tcHV0ZWZlZQovLy8KYXNtIGZ1biBnZXRDb21wdXRlRmVlKGdhc1VzZWQ6IEludCwgaXNNYXN0ZXJjaGFpbjog' +
+ 'Qm9vbCk6IEludCB7IEdFVEdBU0ZFRSB9CgovLy8gR2xvYmFsIGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBn' +
+ 'ZXRDb21wdXRlRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGZsYXRfZ2FzX3ByaWNlYCwgaS5lLiB3aXRob3V0IGEgbWluaW11bSBwcmljZSB0byBwYXkgaWYgdGhlIGBn' +
+ 'YXNVc2VkYCBpcyBsZXNzIHRoYW4gYSBjZXJ0YWluIHRocmVzaG9sZCBjYWxsZWQgYGZsYXRfZ2FzX2xpbWl0YC4gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRo' +
+ 'ZSBgZ2FzVXNlZGAgdGltZXMgdGhlIGN1cnJlbnQgZ2FzIHByaWNlLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2As' +
+ 'IGBiaXRzYCBvciBgc2Vjb25kc2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdpdGggZXhpdCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwov' +
+ 'Ly8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0IGZlZSA9IGdldENvbXB1dGVGZWUoMCwgZmFsc2UpOwovLy8gICAgIGxldCBmZWVOb0ZsYXQg' +
+ 'PSBnZXRTaW1wbGVDb21wdXRlRmVlKDAsIGZhbHNlKTsKLy8vICAgICBsZXQgbWF4RmxhdFByaWNlID0gZmVlIC0gZmVlTm9GbGF0OwovLy8gfQovLy8gYGBgCi8vLwov' +
+ 'Ly8gU2VlOgovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNnZXRzaW1wbGVzdG9yYWdlZmVlCi8vLyAqIGh0dHBzOi8vZG9j' +
+ 'cy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHN0b3JhZ2VmZWUKLy8vCmFzbSBmdW4gZ2V0U2ltcGxlQ29tcHV0ZUZlZShnYXNVc2VkOiBJbnQsIGlz' +
+ 'TWFzdGVyY2hhaW46IEJvb2wpOiBJbnQgeyBHRVRHQVNGRUVTSU1QTEUgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8v' +
+ 'LwovLy8gQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgZm9yd2FyZCBmZWUgaW4gbmFub1RvbmNvaW5zIGBJbnRgIGZvciBhbiBvdXRnb2luZyBtZXNzYWdlIGNvbnNp' +
+ 'c3Rpbmcgb2YgYSBnaXZlbiBudW1iZXIgb2YgYGNlbGxzYCBhbmQgYGJpdHNgLiBVc2VzIHRoZSBwcmljZXMgb2YgdGhlIG1hc3RlcmNoYWluIGlmIGBpc01hc3RlcmNo' +
+ 'YWluYCBpcyBgdHJ1ZXs6dGFjdH1gLCBvdGhlcndpc2UgdGhlIHByaWNlcyBvZiB0aGUgYmFzZWNoYWluLiBUaGUgY3VycmVudCBwcmljZXMgYXJlIG9idGFpbmVkIGZy' +
+ 'b20gdGhlIGNvbmZpZyBwYXJhbSAyNCBmb3IgdGhlIG1hc3RlcmNoYWluIGFuZCBjb25maWcgcGFyYW0gMjUgZm9yIHRoZSBiYXNlY2hhaW4gb2YgVE9OIEJsb2NrY2hh' +
+ 'aW4uCi8vLwovLy8gSWYgYm90aCB0aGUgc291cmNlIGFuZCB0aGUgZGVzdGluYXRpb24gYWRkcmVzc2VzIGFyZSBpbiB0aGUgYmFzZWNoYWluLCB0aGVuIHNwZWNpZnkg' +
+ 'YGlzTWFzdGVyY2hhaW5gIGFzIGBmYWxzZWAuIE90aGVyd2lzZSwgc3BlY2lmeSBgdHJ1ZWAuCi8vLwovLy8gTm90ZSwgdGhhdCB0aGUgdmFsdWVzIG9mIGBjZWxsc2Ag' +
+ 'YW5kIGBiaXRzYCBhcmUgdGFrZW4gbW9kdWxvIHRoZWlyIG1heGltdW0gdmFsdWVzIHBsdXMgMS4gVGhhdCBpcywgc3BlY2lmeWluZyB2YWx1ZXMgaGlnaGVyIHRoYW4g' +
+ 'dGhvc2UgbGlzdGVkIGluIGFjY291bnQgc3RhdGUgbGltaXRzIChgbWF4X21zZ19jZWxsc2AgYW5kIGBtYXhfbXNnX2JpdHNgKSB3aWxsIGhhdmUgdGhlIHNhbWUgcmVz' +
+ 'dWx0IGFzIHdpdGggc3BlY2lmeWluZyB0aGUgZXhhY3QgbGltaXRzLgovLy8KLy8vIEhvd2V2ZXIsIHJlZ2FyZGxlc3Mgb2YgdGhlIHZhbHVlcyBvZiBgY2VsbHNgIGFu' +
+ 'ZCBgYml0c2AsIHRoaXMgZnVuY3Rpb24gYWx3YXlzIGFkZHMgdGhlIG1pbmltdW0gcHJpY2UgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGBsdW1wX3ByaWNlYC4gU2VlIHRo' +
+ 'ZSBleGFtcGxlIGZvciBbYGdldFNpbXBsZUZvcndhcmRGZWUoKXs6dGFjdH1gXSgjZ2V0c2ltcGxlZm9yd2FyZGZlZSkgdG8gZGVyaXZlIGl0LiBJbiBhZGRpdGlvbiwg' +
+ 'bWFrZSBzdXJlIHlvdSB0YWtlIGludG8gYWNjb3VudCB0aGUgZGVkdXBsaWNhdGlvbiBvZiBjZWxscyB3aXRoIHRoZSBzYW1lIGhhc2gsIHNpbmNlIGZvciBleGFtcGxl' +
+ 'IHRoZSByb290IGNlbGwgYW5kIGl0cyBkYXRhIGJpdHMgZG9uJ3QgY291bnQgdG93YXJkcyB0aGUgZm9yd2FyZCBmZWUgYW5kIGFyZSBjb3ZlcmVkIGJ5IHRoZSBgbHVt' +
+ 'cF9wcmljZWAuCi8vLwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBuZWdhdGl2ZSBudW1iZXIgb2YgYGNlbGxzYCBvciBgYml0c2AgdGhyb3cgYW4gZXhjZXB0aW9uIHdp' +
+ 'dGggZXhpdCBjb2RlIDU6IGBJbnRlZ2VyIG91dCBvZiBleHBlY3RlZCByYW5nZWAuCi8vLwovLy8gYGBgdGFjdAovLy8gZnVuIGV4YW1wbGUoKSB7Ci8vLyAgICAgbGV0' +
+ 'IGZlZTogSW50ID0gZ2V0Rm9yd2FyZEZlZSgxXzAwMCwgMV8wMDAsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRh' +
+ 'Y3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNn' +
+ 'ZXRzaW1wbGVmb3J3YXJkZmVlCi8vLyAqIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldG9yaWdpbmFsZndkZmVlCi8vLwphc20g' +
+ 'ZnVuIGdldEZvcndhcmRGZWUoY2VsbHM6IEludCwgYml0czogSW50LCBpc01hc3RlcmNoYWluOiBCb29sKTogSW50IHsgR0VURk9SV0FSREZFRSB9CgovLy8gR2xvYmFs' +
+ 'IGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUuMC4KLy8vCi8vLyBTaW1pbGFyIHRvIGBnZXRGb3J3YXJkRmVlKClgLCBidXQgd2l0aG91dCB0aGUgYGx1' +
+ 'bXBfcHJpY2VgLCBpLmUuIHdpdGhvdXQgdGhlIG1pbmltdW0gcHJpY2UgdG8gcGF5IHJlZ2FyZGxlc3Mgb2YgdGhlIGFtb3VudCBvZiBgY2VsbHNgIG9yIGBiaXRzYC4g' +
+ 'Q2FsY3VsYXRlcyBhbmQgcmV0dXJucyBvbmx5IHRoZSBgY2VsbHNgIHRpbWVzIHRoZSBjdXJyZW50IGNlbGwgcHJpY2UgcGx1cyBgYml0c2AgdGltZXMgdGhlIGN1cnJl' +
+ 'bnQgYml0IHByaWNlLgovLy8KLy8vIEF0dGVtcHRzIHRvIHNwZWNpZnkgbmVnYXRpdmUgbnVtYmVyIG9mIGBjZWxsc2Agb3IgYGJpdHNgIHRocm93IGFuIGV4Y2VwdGlv' +
+ 'biB3aXRoIGV4aXQgY29kZSA1OiBgSW50ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAg' +
+ 'IGxldCBmZWUgPSBnZXRGb3J3YXJkRmVlKDFfMDAwLCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBmZWVOb0x1bXAgPSBnZXRTaW1wbGVGb3J3YXJkRmVlKDFfMDAw' +
+ 'LCAxXzAwMCwgZmFsc2UpOwovLy8gICAgIGxldCBsdW1wUHJpY2UgPSBmZWUgLSBmZWVOb0x1bXA7Ci8vLyB9Ci8vLyBgYGAKLy8vCi8vLyBTZWU6Ci8vLyAqIGh0dHBz' +
+ 'Oi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI2dldHNpbXBsZWZvcndhcmRmZWUKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVm' +
+ 'L2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8KYXNtIGZ1biBnZXRTaW1wbGVGb3J3YXJkRmVlKGNlbGxzOiBJbnQsIGJpdHM6IEludCwgaXNNYXN0ZXJjaGFp' +
+ 'bjogQm9vbCk6IEludCB7IEdFVEZPUldBUkRGRUVTSU1QTEUgfQoKLy8vIEdsb2JhbCBmdW5jdGlvbi4gQXZhaWxhYmxlIHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8g' +
+ 'Q2FsY3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgc28tY2FsbGVkIF9vcmlnaW5hbF8gZm9yd2FyZCBmZWUgaW4gbmFub1RvbmNvaW5zIGBJbnRgIGZvciBhbiBvdXRnb2lu' +
+ 'ZyBtZXNzYWdlIGJhc2VkIG9uIHRoZSBgZndkRmVlYCBvYnRhaW5lZCBmcm9tIHRoZSBpbmNvbWluZyBtZXNzYWdlLiBJZiBib3RoIHRoZSBzb3VyY2UgYW5kIHRoZSBk' +
+ 'ZXN0aW5hdGlvbiBhZGRyZXNzZXMgYXJlIGluIHRoZSBiYXNlY2hhaW4sIHRoZW4gc3BlY2lmeSBgaXNNYXN0ZXJjaGFpbmAgYXMgYGZhbHNlYC4gT3RoZXJ3aXNlLCBz' +
+ 'cGVjaWZ5IGB0cnVlYC4KLy8vCi8vLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWZ1bCB3aGVuIHRoZSBvdXRnb2luZyBtZXNzYWdlIGRlcGVuZHMgaGVhdmlseSBvbiB0aGUg' +
+ 'c3RydWN0dXJlIG9mIHRoZSBpbmNvbWluZyBtZXNzYWdlLCBzbyBtdWNoIHNvIHRoYXQgeW91IGNhbm5vdCBmdWxseSBwcmVkaWN0IHRoZSBmZWUgdXNpbmcgYGdldEZv' +
+ 'cndhcmRGZWUoKWAgYWxvbmUuIEV2ZW4gaWYgeW91IGNvdWxkLCBjYWxjdWxhdGluZyB0aGUgZXhhY3QgZmVlIHdpdGggbmFub1RvbmNvaW4tbGV2ZWwgcHJlY2lzaW9u' +
+ 'IGNhbiBiZSB2ZXJ5IGV4cGVuc2l2ZSwgc28gdGhlIGFwcHJveGltYXRlIHZhbHVlIGdpdmVuIGJ5IHRoaXMgZnVuY3Rpb24gaXMgb2Z0ZW4gZ29vZCBlbm91Z2guCi8v' +
+ 'LwovLy8gQXR0ZW1wdHMgdG8gc3BlY2lmeSBhIG5lZ2F0aXZlIHZhbHVlIG9mIGBmd2RGZWVgIHRocm93IGFuIGV4Y2VwdGlvbiB3aXRoIGV4aXQgY29kZSA1OiBgSW50' +
+ 'ZWdlciBvdXQgb2YgZXhwZWN0ZWQgcmFuZ2VgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBmd2RGZWU6IEludCA9IGNvbnRl' +
+ 'eHQoKS5yZWFkRm9yd2FyZEZlZSgpOwovLy8gICAgIGxldCBvcmlnRmVlOiBJbnQgPSBnZXRPcmlnaW5hbEZ3ZEZlZShmZWUsIGZhbHNlKTsKLy8vIH0KLy8vIGBgYAov' +
+ 'Ly8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0b3JpZ2luYWxmd2RmZWUKLy8vICogaHR0cHM6Ly9k' +
+ 'b2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjZ2V0Zm9yd2FyZGZlZQovLy8gKiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZh' +
+ 'bmNlZCNjb250ZXh0cmVhZGZvcndhcmRmZWUKLy8vCmFzbSBmdW4gZ2V0T3JpZ2luYWxGd2RGZWUoZndkRmVlOiBJbnQsIGlzTWFzdGVyY2hhaW46IEJvb2wpOiBJbnQg' +
+ 'eyBHRVRPUklHSU5BTEZXREZFRSB9CgovLy8gU3RydWN0IHJlcHJlc2VudGluZyB0aGUgc3RhbmRhcmQgYWRkcmVzcyBvbiBUT04gQmxvY2tjaGFpbiB3aXRoIHNpZ25l' +
+ 'ZCA4LWJpdCBgd29ya2NoYWluYCBJRCBhbmQgYW4gdW5zaWduZWQgMjU2LWJpdCBgYWRkcmVzc2AgaW4gdGhlIHNwZWNpZmllZCBgd29ya2NoYWluYC4gQXZhaWxhYmxl' +
+ 'IHNpbmNlIFRhY3QgMS41LjAuCi8vLwovLy8gQXQgdGhlIG1vbWVudCwgb25seSBgd29ya2NoYWluYCBJRHMgdXNlZCBvbiBUT04gYXJlIDAgb2YgdGhlIGJhc2VjaGFp' +
+ 'biBhbmQgLTEgb2YgdGhlIG1hc3RlcmNoYWluLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFy' +
+ 'c2VzdGRhZGRyZXNzCi8vLyAqIGh0dHBzOi8vZ2l0aHViLmNvbS90b24tYmxvY2tjaGFpbi90b24vYmxvYi9tYXN0ZXIvY3J5cHRvL2Jsb2NrL2Jsb2NrLnRsYiNMMTA1' +
+ 'LUwxMDYKLy8vCnN0cnVjdCBTdGRBZGRyZXNzIHsKICAgIHdvcmtjaGFpbjogSW50IGFzIGludDg7CiAgICBhZGRyZXNzOiBJbnQgYXMgdWludDI1NjsKfQoKLy8vIFN0' +
+ 'cnVjdCByZXByZXNlbnRpbmcgdGhlIGFkZHJlc3Mgb2YgdmFyaWFibGUgbGVuZ3RoIHdpdGggc2lnbmVkIDMyLWJpdCBgd29ya2NoYWluYCBJRCBhbmQgYSBgU2xpY2Vg' +
+ 'IGNvbnRhaW5pbmcgdW5zaWduZWQgYGFkZHJlc3NgIGluIHRoZSBzcGVjaWZpZWQgYHdvcmtjaGFpbmAuIEF2YWlsYWJsZSBzaW5jZSBUYWN0IDEuNS4wLgovLy8KLy8v' +
+ 'IFZhcmlhYmxlLWxlbmd0aCBhZGRyZXNzZXMgYXJlIGludGVuZGVkIGZvciBmdXR1cmUgZXh0ZW5zaW9ucywgYW5kIHdoaWxlIHZhbGlkYXRvcnMgbXVzdCBiZSByZWFk' +
+ 'eSB0byBhY2NlcHQgdGhlbSBpbiBpbmJvdW5kIG1lc3NhZ2VzLCB0aGUgc3RhbmRhcmQgKG5vbi12YXJpYWJsZSkgYWRkcmVzc2VzIGFyZSB1c2VkIHdoZW5ldmVyIHBv' +
+ 'c3NpYmxlLgovLy8KLy8vIFNlZToKLy8vICogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2V2YXJhZGRyZXNzCi8vLyAqIGh0' +
+ 'dHBzOi8vZ2l0aHViLmNvbS90b24tYmxvY2tjaGFpbi90b24vYmxvYi9tYXN0ZXIvY3J5cHRvL2Jsb2NrL2Jsb2NrLnRsYiNMMTA3LUwxMDgKLy8vCnN0cnVjdCBWYXJB' +
+ 'ZGRyZXNzIHsKICAgIHdvcmtjaGFpbjogSW50IGFzIGludDMyOwogICAgYWRkcmVzczogU2xpY2U7Cn0KCi8vLyBBc3NlbWJseSBmdW5jdGlvbi4gQXZhaWxhYmxlIHNp' +
+ 'bmNlIFRhY3QgMS41LjAuCi8vLwovLy8gQ29udmVydHMgYSBgU2xpY2VgIGNvbnRhaW5pbmcgYW4gYWRkcmVzcyBpbnRvIHRoZSBgU3RkQWRkcmVzc2AgU3RydWN0IGFu' +
+ 'ZCByZXR1cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCBhZGRyID0gYWRkcmVzcygiRVFEdEZwRXdjRkFFY1JlNW1M' +
+ 'VmgyTjZDMHgtX2hKRU03VzYxX0pMblNGNzRwNHEyIik7Ci8vLyAgICAgbGV0IHBhcnNlZEFkZHIgPSBwYXJzZVN0ZEFkZHJlc3MoYWRkci5hc1NsaWNlKCkpOwovLy8K' +
+ 'Ly8vICAgICBwYXJzZWRBZGRyLndvcmtjaGFpbjsgLy8gMAovLy8gICAgIHBhcnNlZEFkZHIuYWRkcmVzczsgICAvLyAxMDcuLi4yODcKLy8vIH0KLy8vIGBgYAovLy8K' +
+ 'Ly8vIFNlZTogaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2VzdGRhZGRyZXNzCi8vLwphc20gZnVuIHBhcnNlU3RkQWRkcmVz' +
+ 'cyhzbGljZTogU2xpY2UpOiBTdGRBZGRyZXNzIHsgUkVXUklURVNUREFERFIgfQoKLy8vIEFzc2VtYmx5IGZ1bmN0aW9uLiBBdmFpbGFibGUgc2luY2UgVGFjdCAxLjUu' +
+ 'MC4KLy8vCi8vLyBDb252ZXJ0cyBhIGBTbGljZWAgY29udGFpbmluZyBhbiBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCBpbnRvIHRoZSBgVmFyQWRkcmVzc2AgU3Ry' +
+ 'dWN0IGFuZCByZXR1cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGZ1biBleGFtcGxlKCkgewovLy8gICAgIGxldCB2YXJBZGRyU2xpY2UgPSBiZWdpbkNlbGwoKQov' +
+ 'Ly8gICAgICAgICAuc3RvcmVVaW50KDYsIDMpICAgICAvLyB0byByZWNvZ25pemUgdGhlIGZvbGxvd2luZyBhcyBhIFZhckFkZHJlc3MKLy8vICAgICAgICAgLnN0b3Jl' +
+ 'VWludCgxMjMsIDkpICAgLy8gbWFrZSBhZGRyZXNzIG9jY3VweSAxMjMgYml0cwovLy8gICAgICAgICAuc3RvcmVVaW50KDIzNCwgMzIpICAvLyBzcGVjaWZ5IHdvcmtj' +
+ 'aGFpbiBJRCBvZiAyMzQKLy8vICAgICAgICAgLnN0b3JlVWludCgzNDUsIDEyMykgLy8gc3BlY2lmeSBhZGRyZXNzIG9mIDM0NQovLy8gICAgICAgICAuYXNTbGljZSgp' +
+ 'OwovLy8gICAgIGxldCBwYXJzZWRWYXJBZGRyID0gcGFyc2VWYXJBZGRyZXNzKHZhckFkZHJTbGljZSk7Ci8vLwovLy8gICAgIHBhcnNlZFZhckFkZHIud29ya2NoYWlu' +
+ 'OyAgICAgICAgICAgICAvLyAyMzQKLy8vICAgICBwYXJzZWRWYXJBZGRyLmFkZHJlc3M7ICAgICAgICAgICAgICAgLy8gQ1N7Q2VsbHswMDIuLi4yYjN9IGJpdHM6IDQ0' +
+ 'Li4xNjc7IHJlZnM6IDAuLjB9Ci8vLyAgICAgcGFyc2VkVmFyQWRkci5hZGRyZXNzLmxvYWRVaW50KDEyMyk7IC8vIDM0NQovLy8gfQovLy8gYGBgCi8vLwovLy8gU2Vl' +
+ 'OiBodHRwczovL2RvY3MudGFjdC1sYW5nLm9yZy9yZWYvY29yZS1hZHZhbmNlZCNwYXJzZXZhcmFkZHJlc3MKLy8vCmFzbSBmdW4gcGFyc2VWYXJBZGRyZXNzKHNsaWNl' +
+ 'OiBTbGljZSk6IFZhckFkZHJlc3MgeyBSRVdSSVRFVkFSQUREUiB9Cg==';
files['std/crypto.tact'] =
'YXNtIGV4dGVuZHMgZnVuIGhhc2goc2VsZjogQ2VsbCk6IEludCB7IEhBU0hDVSB9Cgphc20gZXh0ZW5kcyBmdW4gaGFzaChzZWxmOiBTbGljZSk6IEludCB7IEhBU0hT' +
'VSB9Cgphc20gZnVuIGNoZWNrU2lnbmF0dXJlKGhhc2g6IEludCwgc2lnbmF0dXJlOiBTbGljZSwgcHVibGljX2tleTogSW50KTogQm9vbCB7IENIS1NJR05VIH0KCmFz' +
diff --git a/stdlib/std/cells.tact b/stdlib/std/cells.tact
index 2bb474d1a..99c5b7443 100644
--- a/stdlib/std/cells.tact
+++ b/stdlib/std/cells.tact
@@ -15,16 +15,17 @@ extends native storeUint(self: Builder, value: Int, bits: Int): Builder;
@name(__tact_store_bool)
extends native storeBool(self: Builder, value: Bool): Builder;
-/// Extension function for the `Builder`. Alias to `Builder.storeBool()`.
+/// Extension function for the `Builder`. Alias to `Builder.storeBool()`. Available since Tact 1.5.0.
///
/// ```tact
-/// let b: Builder = beginCell();
-/// let fizz: Builder = b.storeBit(true); // writes 1
-/// let buzz: Builder = b.storeBit(false); // writes 0
+/// fun example() {
+/// let b: Builder = beginCell();
+/// let fizz: Builder = b.storeBit(true); // writes 1
+/// let buzz: Builder = b.storeBit(false); // writes 0
+/// }
/// ```
///
-/// @since Tact 1.5.0
-/// @see https://docs.tact-lang.org/ref/core-cells#builderstorebit
+/// See: https://docs.tact-lang.org/ref/core-cells#builderstorebit
///
@name(__tact_store_bool)
extends native storeBit(self: Builder, value: Bool): Builder;
@@ -35,12 +36,26 @@ asm(cell self) extends fun storeRef(self: Builder, cell: Cell): Builder { STREF
asm extends fun storeSlice(self: Builder, cell: Slice): Builder { STSLICER }
+/// Extension function for the `Builder`. Available since Tact 1.5.0.
+///
+/// Appends all data from a `Builder` `cell` to the copy of the `Builder`. Returns that copy.
+///
+/// ```tact
+/// fun example() {
+/// let b: Builder = beginCell().storeCoins(42);
+/// let fizz: Builder = beginCell().storeBuilder(b);
+/// b.endCell() == fizz.endCell(); // true
+/// }
+/// ```
+///
+/// See: https://docs.tact-lang.org/ref/core-cells#builderstorebuilder
+///
asm extends fun storeBuilder(self: Builder, cell: Builder): Builder { STBR }
@name(__tact_store_address)
extends native storeAddress(self: Builder, address: Address): Builder;
-/// Extension function for the `Builder`.
+/// Extension function for the `Builder`. Available since Tact 1.5.0.
///
/// If the `cell` is not `null`, stores 1 as a single bit and then reference `cell` into the copy of the `Builder`. Returns that copy.
///
@@ -49,14 +64,15 @@ extends native storeAddress(self: Builder, address: Address): Builder;
/// As a single `Cell` can store up to 4 references, attempts to store more throw an exception with exit code 8: `Cell overflow`.
///
/// ```tact
-/// let b: Builder = beginCell();
-/// let fizz: Builder = b
-/// .storeMaybeRef(emptyCell()) // 1, then empty cell
-/// .storeMaybeRef(null); // 0
+/// fun example() {
+/// let b: Builder = beginCell();
+/// let fizz: Builder = b
+/// .storeMaybeRef(emptyCell()) // 1, then empty cell
+/// .storeMaybeRef(null); // 0
+/// }
/// ```
///
-/// @since Tact 1.5.0
-/// @see https://docs.tact-lang.org/ref/core-cells#builderstoremayberef
+/// See: https://docs.tact-lang.org/ref/core-cells#builderstoremayberef
///
asm(cell self) extends fun storeMaybeRef(self: Builder, cell: Cell?): Builder { STOPTREF }
@@ -83,16 +99,18 @@ asm(-> 1 0) extends mutates fun loadRef(self: Slice): Cell { LDREF }
/// Attempts to preload more data than `Slice` contains throw an exception with exit code 9: `Cell underflow`.
///
/// ```tact
-/// let s1: Slice = beginCell().storeRef(emptyCell()).asSlice();
-/// let fizz: Cell = s1.preloadRef(); // didn't modify s1
-///
-/// let s2: Slice = beginCell()
-/// .storeRef(emptyCell())
-/// .storeRef(s1.asCell())
-/// .asSlice();
-/// let ref1: Cell = s2.preloadRef();
-/// let ref2: Cell = s2.preloadRef();
-/// ref1 == ref2; // true
+/// fun examples() {
+/// let s1: Slice = beginCell().storeRef(emptyCell()).asSlice();
+/// let fizz: Cell = s1.preloadRef(); // didn't modify s1
+///
+/// let s2: Slice = beginCell()
+/// .storeRef(emptyCell())
+/// .storeRef(s1.asCell())
+/// .asSlice();
+/// let ref1: Cell = s2.preloadRef();
+/// let ref2: Cell = s2.preloadRef();
+/// ref1 == ref2; // true
+/// }
/// ```
///
/// See:
@@ -127,15 +145,16 @@ extends native preloadUint(self: Slice, l: Int): Int;
asm(-> 1 0) extends mutates fun loadBool(self: Slice): Bool { 1 LDI }
-/// Extension mutation function for the `Slice`. Alias to `Slice.loadBool()`.
+/// Extension mutation function for the `Slice`. Alias to `Slice.loadBool()`. Available since Tact 1.5.0.
///
/// ```tact
-/// let s: Slice = beginCell().storeBool(true).asSlice();
-/// let fizz: Bool = s.loadBit(); // true
+/// fun example() {
+/// let s: Slice = beginCell().storeBool(true).asSlice();
+/// let fizz: Bool = s.loadBit(); // true
+/// }
/// ```
///
-/// @since Tact 1.5.0
-/// @see https://docs.tact-lang.org/ref/core-cells#sliceloadbit
+/// See: https://docs.tact-lang.org/ref/core-cells#sliceloadbit
///
asm(-> 1 0) extends mutates fun loadBit(self: Slice): Bool { 1 LDI }
diff --git a/stdlib/std/contract.tact b/stdlib/std/contract.tact
index 5a782dfa8..1420e3be2 100644
--- a/stdlib/std/contract.tact
+++ b/stdlib/std/contract.tact
@@ -20,88 +20,223 @@ asm fun myAddress(): Address { MYADDR }
asm fun myBalance(): Int { BALANCE FIRST }
-// Returns gas consumed by VM so far (including this instruction).
+/// Global function. Available since Tact 1.5.0.
+///
+/// Returns the nanoToncoin `Int` amount of gas consumed by TVM in the current transaction so far. The resulting value includes the cost of calling this function.
+///
+/// ```tact
+/// fun example() {
+/// let gas: Int = gasConsumed();
+/// }
+/// ```
+///
+/// See: https://docs.tact-lang.org/ref/core-advanced#gasconsumed
+///
asm fun gasConsumed(): Int { GASCONSUMED }
-// Calculates computation cost in nanotons for transaction that consumes `gas_used` gas.
-asm fun getComputeFee(gas_used: Int, is_masterchain: Bool): Int { GETGASFEE }
+/// Global function. Available since Tact 1.5.0.
+///
+/// Returns the nanoToncoin `Int` amount of the accumulated storage fee debt. Storage fees are deducted from the incoming message value before the new contract balance is calculated.
+///
+/// ```tact
+/// fun example() {
+/// let debt: Int = myStorageDue();
+/// }
+/// ```
+///
+/// See: https://docs.tact-lang.org/ref/core-advanced#mystoragedue
+///
+asm fun myStorageDue(): Int { DUEPAYMENT }
-// Calculates storage fees in nanotons for contract based on current storage prices. `cells` and `bits` are the size of the AccountState (with deduplication, including root cell).
-asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, is_masterchain: Bool): Int { GETSTORAGEFEE }
+/// Global function. Available since Tact 1.5.0.
+///
+/// Calculates and returns the storage fee in nanoToncoins `Int` for storing a contract with a given number of `cells` and `bits` for a number of `seconds`. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 18 of TON Blockchain.
+///
+/// Note, that the values of `cells` and `bits` are taken modulo their maximum values plus 1. That is, specifying values higher than those listed in account state limits (`max_acc_state_cells` and `max_acc_state_bits`) will have the same result as with specifying the exact limits. In addition, make sure you take into account the deduplication of cells with the same hash.
+///
+/// Attempts to specify negative number of `cells`, `bits` or `seconds` throw an exception with exit code 5: `Integer out of expected range`.
+///
+/// ```tact
+/// fun example() {
+/// let fee: Int = getStorageFee(1_000, 1_000, 1_000, false);
+/// }
+/// ```
+///
+/// See:
+/// * https://docs.tact-lang.org/ref/core-advanced#getstoragefee
+/// * https://docs.tact-lang.org/ref/core-advanced#getsimplestoragefee
+///
+asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, isMasterchain: Bool): Int { GETSTORAGEFEE }
-// Calculates forward fees in nanotons for outgoing message. `is_masterchain` is true if the source or the destination is in masterchain, false if both are in basechain. Note, `cells` and `bits` in Message should be counted with account for deduplication and root-is-not-counted rules.
-asm fun getForwardFee(cells: Int, bits: Int, is_masterchain: Bool): Int { GETFORWARDFEE }
+/// Global function. Available since Tact 1.5.0.
+///
+/// Calculates and returns the compute fee in nanoToncoins `Int` for a transaction that consumed `gasUsed` amount of gas. Uses the prices of the masterchain if `isMasterchain` is `true`, otherwise the prices of the basechain. The current prices are obtained from the config param 20 for the masterchain and config param 21 for the basechain of TON Blockchain.
+///
+/// When the `gasUsed` is less than a certain threshold called `flat_gas_limit`, there's a minimum price to pay based on the value of `flat_gas_price`. The less gas is used below this threshold, the higher the minimum price will be. See the example for `getSimpleComputeFee()` to derive that threshold.
+///
+/// Attempts to specify negative value of `gasUsed` throw an exception with exit code 5: `Integer out of expected range`.
+///
+/// ```tact
+/// fun example() {
+/// let fee: Int = getComputeFee(1_000, false);
+/// }
+/// ```
+///
+/// See: https://docs.tact-lang.org/ref/core-advanced#getcomputefee
+///
+asm fun getComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEE }
-// Calculates additional computation cost in nanotons for transaction that consumes additional `gas_used`. In other words, same as `getComputeFee`, but without flat price (just `(gas_used * price) / 2^16`).
-asm fun getSimpleComputeFee(gas_used: Int, is_masterchain: Bool): Int { GETGASFEESIMPLE }
+/// Global function. Available since Tact 1.5.0.
+///
+/// Similar to `getComputeFee()`, but without the `flat_gas_price`, i.e. without a minimum price to pay if the `gasUsed` is less than a certain threshold called `flat_gas_limit`. Calculates and returns only the `gasUsed` times the current gas price.
+///
+/// Attempts to specify negative number of `cells`, `bits` or `seconds` throw an exception with exit code 5: `Integer out of expected range`.
+///
+/// ```tact
+/// fun example() {
+/// let fee = getComputeFee(0, false);
+/// let feeNoFlat = getSimpleComputeFee(0, false);
+/// let maxFlatPrice = fee - feeNoFlat;
+/// }
+/// ```
+///
+/// See:
+/// * https://docs.tact-lang.org/ref/core-advanced#getsimplestoragefee
+/// * https://docs.tact-lang.org/ref/core-advanced#getstoragefee
+///
+asm fun getSimpleComputeFee(gasUsed: Int, isMasterchain: Bool): Int { GETGASFEESIMPLE }
-// Calculates additional forward cost in nanotons for message that contains additional `cells` and `bits`. In other words, same as `getForwardFee`, but without lump price (just `(bits*bit_price + cells*cell_price) / 2^16`).
-asm fun getSimpleForwardFee(cells: Int, bits: Int, is_masterchain: Bool): Int { GETFORWARDFEESIMPLE }
+/// Global function. Available since Tact 1.5.0.
+///
+/// Calculates and returns the forward fee in nanoToncoins `Int` for an outgoing message consisting of a given number of `cells` and `bits`. Uses the prices of the masterchain if `isMasterchain` is `true{:tact}`, otherwise the prices of the basechain. The current prices are obtained from the config param 24 for the masterchain and config param 25 for the basechain of TON Blockchain.
+///
+/// If both the source and the destination addresses are in the basechain, then specify `isMasterchain` as `false`. Otherwise, specify `true`.
+///
+/// Note, that the values of `cells` and `bits` are taken modulo their maximum values plus 1. That is, specifying values higher than those listed in account state limits (`max_msg_cells` and `max_msg_bits`) will have the same result as with specifying the exact limits.
+///
+/// However, regardless of the values of `cells` and `bits`, this function always adds the minimum price based on the value of `lump_price`. See the example for [`getSimpleForwardFee(){:tact}`](#getsimpleforwardfee) to derive it. In addition, make sure you take into account the deduplication of cells with the same hash, since for example the root cell and its data bits don't count towards the forward fee and are covered by the `lump_price`.
+///
+/// Attempts to specify negative number of `cells` or `bits` throw an exception with exit code 5: `Integer out of expected range`.
+///
+/// ```tact
+/// fun example() {
+/// let fee: Int = getForwardFee(1_000, 1_000, false);
+/// }
+/// ```
+///
+/// See:
+/// * https://docs.tact-lang.org/ref/core-advanced#getforwardfee
+/// * https://docs.tact-lang.org/ref/core-advanced#getsimpleforwardfee
+/// * https://docs.tact-lang.org/ref/core-advanced#getoriginalfwdfee
+///
+asm fun getForwardFee(cells: Int, bits: Int, isMasterchain: Bool): Int { GETFORWARDFEE }
-// Calculate `fwd_fee * 2^16 / first_frac`. Can be used to get the original `fwd_fee` of the message (as replacement for hardcoded values) from `fwd_fee` parsed from incoming message. `is_masterchain` is true if the source or the destination is in masterchain, false if both are in basechain.
-asm fun getOriginalFwdFee(fwd_fee: Int, is_masterchain: Bool): Int { GETORIGINALFWDFEE }
+/// Global function. Available since Tact 1.5.0.
+///
+/// Similar to `getForwardFee()`, but without the `lump_price`, i.e. without the minimum price to pay regardless of the amount of `cells` or `bits`. Calculates and returns only the `cells` times the current cell price plus `bits` times the current bit price.
+///
+/// Attempts to specify negative number of `cells` or `bits` throw an exception with exit code 5: `Integer out of expected range`.
+///
+/// ```tact
+/// fun example() {
+/// let fee = getForwardFee(1_000, 1_000, false);
+/// let feeNoLump = getSimpleForwardFee(1_000, 1_000, false);
+/// let lumpPrice = fee - feeNoLump;
+/// }
+/// ```
+///
+/// See:
+/// * https://docs.tact-lang.org/ref/core-advanced#getsimpleforwardfee
+/// * https://docs.tact-lang.org/ref/core-advanced#getforwardfee
+///
+asm fun getSimpleForwardFee(cells: Int, bits: Int, isMasterchain: Bool): Int { GETFORWARDFEESIMPLE }
-// Current debt for storage fee in nanotons.
-asm fun myStorageDue(): Int { DUEPAYMENT }
+/// Global function. Available since Tact 1.5.0.
+///
+/// Calculates and returns the so-called _original_ forward fee in nanoToncoins `Int` for an outgoing message based on the `fwdFee` obtained from the incoming message. If both the source and the destination addresses are in the basechain, then specify `isMasterchain` as `false`. Otherwise, specify `true`.
+///
+/// This function is useful when the outgoing message depends heavily on the structure of the incoming message, so much so that you cannot fully predict the fee using `getForwardFee()` alone. Even if you could, calculating the exact fee with nanoToncoin-level precision can be very expensive, so the approximate value given by this function is often good enough.
+///
+/// Attempts to specify a negative value of `fwdFee` throw an exception with exit code 5: `Integer out of expected range`.
+///
+/// ```tact
+/// fun example() {
+/// let fwdFee: Int = context().readForwardFee();
+/// let origFee: Int = getOriginalFwdFee(fee, false);
+/// }
+/// ```
+///
+/// See:
+/// * https://docs.tact-lang.org/ref/core-advanced#getoriginalfwdfee
+/// * https://docs.tact-lang.org/ref/core-advanced#getforwardfee
+/// * https://docs.tact-lang.org/ref/core-advanced#contextreadforwardfee
+///
+asm fun getOriginalFwdFee(fwdFee: Int, isMasterchain: Bool): Int { GETORIGINALFWDFEE }
-/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`.
+/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. Available since Tact 1.5.0.
///
/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain.
///
-/// @since Tact 1.5.0
-/// @see https://docs.tact-lang.org/ref/core-advanced#parsestdaddress
-/// @see https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106
+/// See:
+/// * https://docs.tact-lang.org/ref/core-advanced#parsestdaddress
+/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106
///
struct StdAddress {
workchain: Int as int8;
address: Int as uint256;
}
-/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`.
+/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. Available since Tact 1.5.0.
///
/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible.
///
-/// @since Tact 1.5.0
-/// @see https://docs.tact-lang.org/ref/core-advanced#parsevaraddress
-/// @see https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108
+/// See:
+/// * https://docs.tact-lang.org/ref/core-advanced#parsevaraddress
+/// * https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108
///
struct VarAddress {
workchain: Int as int32;
address: Slice;
}
+/// Assembly function. Available since Tact 1.5.0.
+///
/// Converts a `Slice` containing an address into the `StdAddress` Struct and returns it.
///
/// ```tact
-/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");
-/// let parsedAddr = parseStdAddress(addr.asSlice());
+/// fun example() {
+/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2");
+/// let parsedAddr = parseStdAddress(addr.asSlice());
///
-/// parsedAddr.workchain; // 0
-/// parsedAddr.address; // 107...287
+/// parsedAddr.workchain; // 0
+/// parsedAddr.address; // 107...287
+/// }
/// ```
///
-/// @since Tact 1.5.0
-/// @see https://docs.tact-lang.org/ref/core-advanced#parsestdaddress
+/// See: https://docs.tact-lang.org/ref/core-advanced#parsestdaddress
///
asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR }
+/// Assembly function. Available since Tact 1.5.0.
+///
/// Converts a `Slice` containing an address of variable length into the `VarAddress` Struct and returns it.
///
/// ```tact
-/// let varAddrSlice = beginCell()
-/// .storeUint(6, 3) // to recognize the following as a VarAddress
-/// .storeUint(123, 9) // make address occupy 123 bits
-/// .storeUint(234, 32) // specify workchain ID of 234
-/// .storeUint(345, 123) // specify address of 345
-/// .asSlice();
-/// let parsedVarAddr = parseVarAddress(varAddrSlice);
-///
-/// parsedVarAddr.workchain; // 234
-/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}
-/// parsedVarAddr.address.loadUint(123); // 345
+/// fun example() {
+/// let varAddrSlice = beginCell()
+/// .storeUint(6, 3) // to recognize the following as a VarAddress
+/// .storeUint(123, 9) // make address occupy 123 bits
+/// .storeUint(234, 32) // specify workchain ID of 234
+/// .storeUint(345, 123) // specify address of 345
+/// .asSlice();
+/// let parsedVarAddr = parseVarAddress(varAddrSlice);
+///
+/// parsedVarAddr.workchain; // 234
+/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0}
+/// parsedVarAddr.address.loadUint(123); // 345
+/// }
/// ```
///
-/// @since Tact 1.5.0
-/// @see https://docs.tact-lang.org/ref/core-advanced#parsevaraddress
+/// See: https://docs.tact-lang.org/ref/core-advanced#parsevaraddress
///
asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }